import logging

__PATH__ = "."
__CONFIG__ = None


def signal(obj, label, type):
    return (obj, label, type)


def edge(src, trg, thread):
    return (src, trg, thread)


def format_name(name):
    return name.replace(".", "_")


def type_bytes_count(mtype):
    if mtype.startswith("uint"):
        return int(mtype[4:]) // 8
    if mtype.startswith("int"):
        return int(mtype[3:]) // 8
    if mtype.startswith("float"):
        return int(mtype[5:]) // 8
    if mtype == "bool":
        return 1
    logging.debug(f"Type `{mtype}` unknow, size 1 byte")
    return 1


def signal_byte_size(sig):
    noe = 1 if "NumberOfElements" not in sig else int(sig["NumberOfElements"])
    nod = 1 if "NumberOfDimensions" not in sig else int(sig["NumberOfDimensions"])
    nod = nod if nod > 0 else 1
    noe = noe if noe > 0 else 1
    nos = 1 if "Samples" not in sig else int(sig["Samples"])
    if "Type" in sig:
        bytes = type_bytes_count(sig["Type"])
    else:
        bytes = type_bytes_count(signal_type(sig)[0])
    tot = noe * nod * nos

    if "Ranges" in sig:
        tot = 0
        for i0, ie in sig["Ranges"]:
            tot += int(ie) - int(i0) + 1

    return tot * bytes


def signal_type(sig):
    if "Type" in sig:
        type_name = sig["Type"]
    else:
        type_name = "uint32"
    noe = int(sig["NumberOfElements"]) if "NumberOfElements" in sig else 1
    nod = int(sig["NumberOfDimensions"]) if "NumberOfDimensions" in sig else 1
    nod = nod if nod > 0 else 1
    dim = noe * nod
    range = sig["Ranges"] if "Ranges" in sig else []
    return (type_name, dim, range)


def type_to_string(mtype):
    range = ""
    if mtype[2]:
        range = (
            "("
            + ", ".join(
                [
                    str(i0) if i0 == i1 else (str(i0) + ":" + str(int(i1) + 1))
                    for i0, i1 in mtype[2]
                ]
            )
            + ")"
        )
    if mtype[1] != 1:
        return f"{mtype[0]}[{mtype[1]}]{range}"
    return mtype[0] + range


def signal_alias(name, signal):
    return name if "Alias" not in signal else signal["Alias"]


def path():
    global __PATH__
    return __PATH__


def set_path(path):
    global __PATH__
    __PATH__ = path


def set_config(config):
    global __CONFIG__
    __CONFIG__ = config


def config():
    global __CONFIG__
    return __CONFIG__


def build():
    global __CONFIG__
    return str(__CONFIG__.build).upper() == "TRUE"
