#!/usr/bin/env python3.5
# Copyright 2017 Digital
#
# This file is part of BeeWatch.
#
# BeeWatch is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BeeWatch is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BeeWatch.  If not, see <http://www.gnu.org/licenses/>.
## Imports
# Python imports
import logging
import logging.handlers
import sys
import time
import traceback
# Third party imports
import blinker
import curio

import digilib.network

log = logging.getLogger(__name__+"")

_controllers = {}
_commands = {}


class Configure(object):
    warnings = True
    """
    Configure BeeWatch from a dict
    This class is inspired by logging.config
    (https://github.com/python/cpython/blob/3.6/Lib/logging/config.py)
    """

    def __init__(self,config):
        super(Configure,self).__init__()
        self.configure(config)

    def configure(self,config):
        retconf = {
            "controllers":{},
            "commands":{},
        }
        # Configure the Controllers first
        for name,properties in config.get("controllers",{}).items():
            log.debug("configuring {}".format(name))
            target = properties.pop("target")
            if not callable(target):
                target = self.str_to_callable(target)
            ctrl = target(**properties)
            if name in _controllers.keys() and self.warnings:
                log.warn("overwriting controller "+name)
            _controllers[name] = ctrl
            retconf["controllers"][name] = ctrl

        # Next configure the commands
        for name,properties in config.get("commands",{}).items():
            log.debug("configuring {}".format(name))
            function = properties.pop("function")
            ctrl = properties.pop("controller")
            if not callable(ctrl):
                if ctrl not in _controllers.keys():
                    raise ValueError("No controller found with name " + ctrl)
            ctrl = _controllers[ctrl]
            if not hasattr(ctrl,function):
                raise ValueError(
                    "{} doesn't have attribute {}".format(ctrl,function))
            function = getattr(ctrl,function)
            if name in _commands.keys() and self.warnings:
                log.warn("overwriting command "+name)
            _commands[name] = function
            retconf["commands"][name] = function

    def str_to_callable(self,dotted_str):
        parts = dotted_str.split(".")
        next_to_import = parts.pop(0)
        converted = __import__(next_to_import)
        for p in parts:
            next_to_import += "." + p
            if not hasattr(converted,p):
                converted = __import__(next_to_import)
            converted = getattr(converted,p)
        return converted
































#
