import importlib
import sys

from typing import Any, Type, Union
from omegaconf import DictConfig

def dynamic_import(name: str, fallback: bool = True) -> Any:
    if ":" in name:
        package_name, object_name = name.rsplit(":", 1)
    elif fallback:
        package_name, object_name = name.rsplit(".", 1)
    else:
        package_name, object_name = name, None

    # Append current working directory into pythonpath.
    # This avoids to set it manually when importing custom modules.
    sys.path.append(".")
    package = importlib.import_module(package_name)
    if object_name is None:
        return package
    obj = package
    for object_key in object_name.split("."):
        obj = getattr(obj, object_key)
    return obj

def instantiate_class(arguments: Union[dict, DictConfig], **other_kwargs) -> Any:
    arguments = dict(arguments)
    classname = arguments["classname"]
    del arguments["classname"]
    return dynamic_import(classname)(**arguments, **other_kwargs)

def get_class(arguments: Union[dict, DictConfig]) -> Type:
    return dynamic_import(arguments["classname"])

def get_arguments(arguments: Union[dict, DictConfig]) -> dict:
    arguments = dict(arguments)
    if "classname" in arguments:
        del arguments["classname"]
    return arguments