import builtins
import importlib
import re
from typing import List, Type


def get_class_path(cls: type) -> str:
    """
    The full import path of the type
    """
    if hasattr(cls, "__class_path__"):
        cls = cls.__class_path__
    return re.search("'(.*)'", str(cls))[1]


def get_class(class_path: str) -> Type[object]:
    return GetClass(class_path).cls


class GetClass:
    def __init__(self, class_path):
        self.class_path = class_path

    @property
    def _class_path_array(self) -> List[str]:
        """
        A list of strings describing the module and class of the
        real object represented here
        """
        return self.class_path.split(".")

    @property
    def _class_name(self) -> str:
        """
        The name of the real class
        """
        return self._class_path_array[-1]

    @property
    def _module_path(self) -> str:
        """
        The path of the module containing the real class
        """
        return ".".join(self._class_path_array[:-1])

    @property
    def _module(self):
        """
        The module containing the real class
        """
        try:
            return importlib.import_module(self._module_path)
        except ValueError:
            return builtins

    @property
    def cls(self) -> Type[object]:
        """
        The class of the real object
        """
        return getattr(self._module, self._class_name)
