from __future__ import unicode_literals
from __future__ import absolute_import

from .registry import ElementRegistry, Meta
from .. import namespaces
from ..compat import iterkeys, itervalues

from itertools import chain
import inspect
import re

# _meta = ['logic_skip',
#          'virtual_tag',
#          'is_call',
#          'is_try',
#          'is_loop',
#          'app_first_arg',
#          'text_nodes',
#          'trap_exceptions',
#          'trans']


class ElementBaseMeta(type):
    default_namespace = namespaces.default

    @classmethod
    def make_tag_name(cls, name, _re_tag_name=re.compile(r"[A-Z]+[a-z]*")):
        """Convert a tag name from CamelCase to lower-case-and-hyphens"""
        def repl(match):
            return "-" + match.group(0)
        return _re_tag_name.sub(repl, name).strip('_-').lower()

    def __new__(cls, name, base, attrs):
        if '_registry' in attrs:
            registry = attrs['_registry']
        else:
            registry = ElementRegistry.get_default()

        register_element = registry.register_element

        new_class = type.__new__(cls, name, base, attrs)
        xmlns = getattr(new_class, 'xmlns', cls.default_namespace)
        tag_name = cls.make_tag_name(getattr(new_class.Meta, 'tag_name', name))
        if not getattr(new_class.Meta, 'dynamic', False):
            register_element(xmlns, tag_name, new_class)
        new_class._tag_name = tag_name
        attributes = new_class._get_tag_attributes()
        new_class._tag_attributes = attributes
        new_class._tag_attributes_set = frozenset(chain(iterkeys(attributes), ('libname', 'docname', 'if')))
        new_class._required_tag_attributes = frozenset(attribute.name for attribute in itervalues(new_class._tag_attributes) if attribute.required)
        new_class._tag_doc = new_class.__doc__

        new_class._definition = inspect.getsourcefile(new_class)

        _meta = new_class._meta = Meta()
        _meta.__dict__.update(new_class.Meta.__dict__)

        return new_class
