"""OpenEmbedded variable typing support

Types are defined in the metadata by name, using the 'type' flag on a
variable.  Other flags may be utilized in the construction of the types.  See
the arguments of the type's factory for details.
"""

import inspect
import oe.types as types
try:
    # Python 3.7+
    from collections.abc import Callable
except ImportError:
    # Python < 3.7
    from collections import Callable

available_types = {}

class MissingFlag(TypeError):
    """A particular flag is required to construct the type, but has not been
    provided."""
    def __init__(self, flag, type):
        self.flag = flag
        self.type = type
        TypeError.__init__(self)

    def __str__(self):
        return "Type '%s' requires flag '%s'" % (self.type, self.flag)

def factory(var_type):
    """Return the factory for a specified type."""
    if var_type is None:
        raise TypeError("No type specified. Valid types: %s" %
                        ', '.join(available_types))
    try:
        return available_types[var_type]
    except KeyError:
        raise TypeError("Invalid type '%s':\n  Valid types: %s" %
                        (var_type, ', '.join(available_types)))

def create(value, var_type, **flags):
    """Create an object of the specified type, given the specified flags and
    string value."""
    obj = factory(var_type)
    objflags = {}
    for flag in obj.flags:
        if flag not in flags:
            if flag not in obj.optflags:
                raise MissingFlag(flag, var_type)
        else:
            objflags[flag] = flags[flag]

    return obj(value, **objflags)

def get_callable_args(obj):
    """Grab all but the first argument of the specified callable, returning
    the list, as well as a list of which of the arguments have default
    values."""
    if type(obj) is type:
        obj = obj.__init__

    sig = inspect.signature(obj)
    args = list(sig.parameters.keys())
    defaults = list(s for s in sig.parameters.keys() if sig.parameters[s].default != inspect.Parameter.empty)
    flaglist = []
    if args:
        if len(args) > 1 and args[0] == 'self':
            args = args[1:]
        flaglist.extend(args)

    optional = set()
    if defaults:
        optional |= set(flaglist[-len(defaults):])
    return flaglist, optional

def factory_setup(name, obj):
    """Prepare a factory for use."""
    args, optional = get_callable_args(obj)
    extra_args = args[1:]
    if extra_args:
        obj.flags, optional = extra_args, optional
        obj.optflags = set(optional)
    else:
        obj.flags = obj.optflags = ()

    if not hasattr(obj, 'name'):
        obj.name = name

def register(name, factory):
    """Register a type, given its name and a factory callable.

    Determines the required and optional flags from the factory's
    arguments."""
    factory_setup(name, factory)
    available_types[factory.name] = factory


# Register all our included types
for name in dir(types):
    if name.startswith('_'):
        continue

    obj = getattr(types, name)
    if not isinstance(obj, Callable):
        continue

    register(name, obj)
