#    Copyright 2014-2015 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
from inspect import isclass

from devlib.utils.misc import walk_modules
from devlib.utils.types import identifier


__module_cache = {}


class Module(object):

    name = None
    kind = None
    # This is the stage at which the module will be installed. Current valid
    # stages are:
    #  'early' -- installed when the Target is first created. This should be
    #             used for modules that do not rely on the main connection
    #             being established (usually because the commumnitcate with the
    #             target through some sorto of secondary connection, e.g. via
    #             serial).
    #  'connected' -- installed when a connection to to the target has been
    #                 established. This is the default.
    stage = 'connected'

    @staticmethod
    def probe(target):
        raise NotImplementedError()

    @classmethod
    def install(cls, target, **params):
        if cls.kind is not None:
            attr_name = identifier(cls.kind)
        else:
            attr_name = identifier(cls.name)
        if hasattr(target, attr_name):
            existing_module = getattr(target, attr_name)
            existing_name = getattr(existing_module, 'name', str(existing_module))
            message = 'Attempting to install module "{}" which already exists (new: {}, existing: {})'
            raise ValueError(message.format(attr_name, cls.name, existing_name))
        setattr(target, attr_name, cls(target, **params))

    def __init__(self, target):
        self.target = target
        self.logger = logging.getLogger(self.__class__.__name__)


class HardRestModule(Module):  # pylint: disable=R0921

    kind = 'hard_reset'

    def __call__(self):
        raise NotImplementedError()


class BootModule(Module):  # pylint: disable=R0921

    kind = 'boot'

    def __call__(self):
        raise NotImplementedError()

    def update(self, **kwargs):
        for name, value in kwargs.iteritems():
            if not hasattr(self, name):
                raise ValueError('Unknown parameter "{}" for {}'.format(name, self.name))
            self.logger.debug('Updating "{}" to "{}"'.format(name, value))
            setattr(self, name, value)


class FlashModule(Module):

    kind = 'flash'

    def __call__(self, image_bundle=None, images=None, boot_config=None):
        raise NotImplementedError()


def get_module(mod):
    if not __module_cache:
        __load_cache()

    if isinstance(mod, basestring):
        try:
            return __module_cache[mod]
        except KeyError:
            raise ValueError('Module "{}" does not exist'.format(mod))
    elif issubclass(mod, Module):
        return mod
    else:
        raise ValueError('Not a valid module: {}'.format(mod))


def register_module(mod):
    if not issubclass(mod, Module):
        raise ValueError('A module must subclass devlib.Module')
    if mod.name is None:
        raise ValueError('A module must define a name')
    if mod.name in __module_cache:
        raise ValueError('Module {} already exists'.format(mod.name))
    __module_cache[mod.name] = mod


def __load_cache():
    for module in walk_modules('devlib.module'):
        for obj in vars(module).itervalues():
            if isclass(obj) and issubclass(obj, Module) and obj.name:
                register_module(obj)
