# Path: draftjs_exporter/engines/base.py
# class DOMEngine(object):
#     """
#     Parent class of all DOM implementations.
#     """
# 
#     @staticmethod
#     def create_tag(type_: Tag, attr: Optional[Attr] = None) -> Any:
#         """
#         Creates and returns a tree node of the given type and attributes.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def parse_html(markup: HTML) -> Element:
#         """
#         Creates nodes based on the input html.
#         Note: this method is used in component implementations only, and
#         is not required for the exporter to operate.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def append_child(elt: Element, child: Element) -> Any:
#         """
#         Appends the given child node in the children of elt.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def render(elt: Element) -> HTML:
#         """
#         Renders a given element to HTML.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def render_debug(elt: Element) -> HTML:
#         """
#         Renders a given element to HTML.
#         Note: this method is only used for draftjs_exporter's tests, and
#         is not required for the exporter to operate.
#         """
#         raise NotImplementedError
# 
# Path: draftjs_exporter/types.py
# HTML = str
# 
# Path: draftjs_exporter/utils/module_loading.py
# def import_string(dotted_path: str) -> Any:
#     """
#     Import a dotted module path and return the attribute/class designated by the
#     last name in the path. Raise ImportError if the import failed.
# 
#     Taken from Django:
#     https://github.com/django/django/blob/f6bd00131e687aedf2719ad31e84b097562ca5f2/django/utils/module_loading.py#L7-L24
#     """
#     try:
#         module_path, class_name = dotted_path.rsplit(".", 1)
#     except ValueError:
#         raise ImportError(f"{dotted_path} doesn't look like a module path")
# 
#     module = import_module(module_path)
# 
#     try:
#         return getattr(module, class_name)
#     except AttributeError:
#         raise ImportError(
#             f'Module "{module_path}" does not define a "{class_name}" attribute/class'
#         )


import re
from typing import Any, Optional
from draftjs_exporter.engines.base import DOMEngine
from draftjs_exporter.types import HTML, Element, Props, RenderableType
from draftjs_exporter.utils.module_loading import import_string


# https://gist.github.com/yahyaKacem/8170675
_first_cap_re = re.compile(r"(.)([A-Z][a-z]+)")
_all_cap_re = re.compile("([a-z0-9])([A-Z])")


class DOM(object):
    """
    Component building API, abstracting the DOM implementation.
    """

    HTML5LIB = "draftjs_exporter.engines.html5lib.DOM_HTML5LIB"
    LXML = "draftjs_exporter.engines.lxml.DOM_LXML"
    STRING = "draftjs_exporter.engines.string.DOMString"

    dom: DOMEngine = None  # type: ignore

    @staticmethod
    def camel_to_dash(camel_cased_str: str) -> str:
        sub2 = _first_cap_re.sub(r"\1-\2", camel_cased_str)
        dashed_case_str = _all_cap_re.sub(r"\1-\2", sub2).lower()
        return dashed_case_str.replace("--", "-")

    @classmethod
    def use(cls, engine: str) -> None:
        """
        Choose which DOM implementation to use.
        """

# Path: draftjs_exporter/engines/base.py
# class DOMEngine(object):
#     """
#     Parent class of all DOM implementations.
#     """
# 
#     @staticmethod
#     def create_tag(type_: Tag, attr: Optional[Attr] = None) -> Any:
#         """
#         Creates and returns a tree node of the given type and attributes.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def parse_html(markup: HTML) -> Element:
#         """
#         Creates nodes based on the input html.
#         Note: this method is used in component implementations only, and
#         is not required for the exporter to operate.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def append_child(elt: Element, child: Element) -> Any:
#         """
#         Appends the given child node in the children of elt.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def render(elt: Element) -> HTML:
#         """
#         Renders a given element to HTML.
#         """
#         raise NotImplementedError
# 
#     @staticmethod
#     def render_debug(elt: Element) -> HTML:
#         """
#         Renders a given element to HTML.
#         Note: this method is only used for draftjs_exporter's tests, and
#         is not required for the exporter to operate.
#         """
#         raise NotImplementedError
# 
# Path: draftjs_exporter/types.py
# HTML = str
# 
# Path: draftjs_exporter/utils/module_loading.py
# def import_string(dotted_path: str) -> Any:
#     """
#     Import a dotted module path and return the attribute/class designated by the
#     last name in the path. Raise ImportError if the import failed.
# 
#     Taken from Django:
#     https://github.com/django/django/blob/f6bd00131e687aedf2719ad31e84b097562ca5f2/django/utils/module_loading.py#L7-L24
#     """
#     try:
#         module_path, class_name = dotted_path.rsplit(".", 1)
#     except ValueError:
#         raise ImportError(f"{dotted_path} doesn't look like a module path")
# 
#     module = import_module(module_path)
# 
#     try:
#         return getattr(module, class_name)
#     except AttributeError:
#         raise ImportError(
#             f'Module "{module_path}" does not define a "{class_name}" attribute/class'
#         )


# Path: draftjs_exporter/dom.py
import re
from typing import Any, Optional
from draftjs_exporter.engines.base import DOMEngine
from draftjs_exporter.types import HTML, Element, Props, RenderableType
from draftjs_exporter.utils.module_loading import import_string



# https://gist.github.com/yahyaKacem/8170675
_first_cap_re = re.compile(r"(.)([A-Z][a-z]+)")
_all_cap_re = re.compile("([a-z0-9])([A-Z])")


class DOM(object):
    """
    Component building API, abstracting the DOM implementation.
    """

    HTML5LIB = "draftjs_exporter.engines.html5lib.DOM_HTML5LIB"
    LXML = "draftjs_exporter.engines.lxml.DOM_LXML"
    STRING = "draftjs_exporter.engines.string.DOMString"

    dom: DOMEngine = None  # type: ignore

    @staticmethod
    def camel_to_dash(camel_cased_str: str) -> str:
        sub2 = _first_cap_re.sub(r"\1-\2", camel_cased_str)
        dashed_case_str = _all_cap_re.sub(r"\1-\2", sub2).lower()
        return dashed_case_str.replace("--", "-")

    @classmethod
    def use(cls, engine: str) -> None:
        """
        Choose which DOM implementation to use.
        """

        cls.dom = import_string(engine)