import os
import logging
from collections import namedtuple


from lxml import etree

from .config import get_packages

from .cmake_helper import get_data_path


ArmarXProxyInfo = namedtuple(
    "ArmarXProxyInfo",
    ["package_name", "fullname", "include_path", "default_name", "type"],
)

logger = logging.getLogger(__name__)


def get_ice_default_name(cls) -> str:
    mapping = build_mapping()
    fullname = f"{cls.__module__}.{cls.__name__}"
    if mapping.get(fullname, None):
        variant_info = mapping[fullname]
        default_name = variant_info.default_name
    else:
        default_name = cls.__name__
        default_name = default_name.rstrip("Prx")
        default_name = default_name.rstrip("Interface")
    return default_name


def _load_variant_info(armarx_package_name: str):
    mapping = dict()
    data_path = get_data_path(armarx_package_name)
    if not data_path:
        logger.warning("unable to get data path for package %s", armarx_package_name)
        return mapping
    variant_path = os.path.join(
        data_path[0],
        armarx_package_name,
        "VariantInfo-{}.xml".format(armarx_package_name),
    )
    if not os.path.isfile(variant_path):
        logger.warning(
            "variant info does not exists for package %s", armarx_package_name
        )
        return mapping
    tree = etree.parse(variant_path)
    start_pos = len(armarx_package_name + "/interface/")
    for definition_type in ["Proxy", "Topic", "Class"]:
        for nav in tree.xpath("//VariantInfo/Lib/" + definition_type):
            fullname = nav.get("typeName").replace("::", ".")
            if not "." in fullname:
                fullname = f"armarx.{fullname}"
            slice_include_path = nav.get("include")[start_pos:-2] + ".ice"
            if definition_type == "Class":
                proxy_default_name = ""
            else:
                proxy_default_name = nav.get("propertyDefaultValue")

            mapping[fullname] = ArmarXProxyInfo(
                armarx_package_name,
                fullname,
                slice_include_path,
                proxy_default_name,
                definition_type,
            )
            # also make the interface available.
            # the suffix Prx is autogenerated from the slice definition
    return mapping


def build_mapping():
    global_mapping = dict()
    armarx_packages = get_packages()
    for package_name in armarx_packages.split(","):
        global_mapping.update(_load_variant_info(package_name))
    return global_mapping


slice_mapping = build_mapping()
