# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
import logging as log
from collections import OrderedDict
from functools import partial

from reggen.validate import check_bool, check_int, val_types

from .item import Node, NodeType
from .xbar import Xbar

from .lib import simplify_addr

# val_types = {
#     'd': ["int", "integer (binary 0b, octal 0o, decimal, hex 0x)"],
#     'x': ["xint", "x for undefined otherwise int"],
#     'b': [
#         "bitrange", "bit number as decimal integer, \
#                     or bit-range as decimal integers msb:lsb"
#     ],
#     'l': ["list", "comma separated list enclosed in `[]`"],
#     'ln': ["name list", 'comma separated list enclosed in `[]` of '\
#            'one or more groups that have just name and dscr keys.'\
#            ' e.g. `{ name: "name", desc: "description"}`'],
#     'lnw': ["name list+", 'name list that optionally contains a width'],
#     'lp': ["parameter list", 'parameter list having default value optionally'],
#     'g': ["group", "comma separated group of key:value enclosed in `{}`"],
#     'lg': ["list of group", "comma separated group of key:value enclosed in `{}`"\
#            " the second entry of the list is the sub group format"],
#     's': ["string", "string, typically short"],
#     't': ["text", "string, may be multi-line enclosed in `'''` "\
#           "may use `**bold**`, `*italic*` or `!!Reg` markup"],
#     'T': ["tuple", "tuple enclosed in ()"],
#     'pi': ["python int", "Native Python type int (generated)"],
#     'pb': ["python Bool", "Native Python type Bool (generated)"],
#     'pl': ["python list", "Native Python type list (generated)"],
#     'pe': ["python enum", "Native Python type enum (generated)"]
# }
addr = {
    'name': 'Address configuration',
    'description':
    '''Device Node address configuration. It contains the base address and the size in bytes.
''',
    'required': {
        'base_addr':
        ['d', 'Base address of the device. It is required for the device'],
        'size_byte':
        ['d', 'Memory space of the device. It is required for the device'],
    },
    'optional': {},
    'added': {}
}

node = {
    'name': 'Node configuration',
    'description': '''
Crossbar node description. It can be host, device, or internal nodes.
''',
    'required': {
        'name': ['s', 'Module instance name'],
        'stub': ['pb', 'Real node or stub.  Stubs only occupy address ranges'],
        'type': [
            's',
            'Module type: {"host", "device", "async", "socket_1n", "socket_m1"}'
        ],
    },
    'optional': {
        'clock': ['s', 'main clock of the port'],
        'reset': ['s', 'main reset of the port'],
        'pipeline': ['pb', 'If true, pipeline is added in front of the port'],
        'pipeline_byp': [
            'pb', 'Pipeline bypass. If true, '
            'request/response are not latched'
        ],
        'inst_type': ['s', 'Instance type'],
        'xbar': ['pb', 'If true, the node is connected to another Xbar'],
        'addr_range': ['lg', addr]
    },
    'added': {}
}

root = {
    'name': 'Top configuration',
    'description': '''
Crossbar configuration format.
''',
    'required': {
        'name': ['s', 'Name of the crossbar'],
        'clock': [
            's', 'Main clock. Internal components use this clock.'
            ' If not specified, it is assumed to be in main clock domain'
        ],
        'reset': ['s', 'Main reset'],
        'connections':
        ['g', "List of edge. Key is host, entry in value list is device"],
        'clock_connections': ['g', 'list of clocks'],
        'nodes': ['lg', node]
    },
    'optional': {
        'type': ['s', 'Indicate Hjson type. "xbar" always if exist'],
    },
    'added': {
        'reset_connections': [
            'g', "Generated by topgen. Key is the reset signal inside IP"
            " and value is the top reset signal"
        ],
    }
}


def check_keys(obj, control, prefix=""):
    """ Check the keys recursively.

    The control parameter is a control group to check obj data structure.
    """
    error = 0

    # required
    for k, v in control["required"].items():
        if k not in obj:
            error += 1
            log.error(prefix + " missing required key " + k)

    # Check every fields' correctness
    for k, v in obj.items():
        checker = ['', '']
        prefix_name = prefix + " " + k

        if k in control["required"]:
            checker = control["required"][k]
        elif k in control["optional"]:
            checker = control["optional"][k]
        elif k in control["added"]:
            log.warning(prefix + " contains generated key " + k)
            checker = control["added"][k]
        else:
            log.warning(prefix + " contains extra key " + k)
            continue

        # Type and value check
        if not checker[0] in val_types:
            log.error(prefix +
                      " field {} is undefined type. Check val_types {}".format(
                          k, checker[0]))
        if checker[0] == 'lg':
            # List of subgroup
            error += sum(
                map(
                    partial(check_keys, control=checker[1],
                            prefix=prefix_name), obj[k]))
        elif checker[0] == 'g':
            # if second entry isn't string type, call recursively
            if isinstance(checker[1], str):
                log.info(
                    "Skipping {} as no further control group is given".format(
                        prefix_name))
                continue

            error += check_keys(obj=obj[k],
                                control=checker[1],
                                prefix=prefix_name)

        elif checker[0] == 'd':
            int_v, err = check_int(obj[k], prefix_name)
            if err:
                error += 1

        elif checker[0] == 's' or checker[0] == 't':
            # don't care the string
            pass

        elif checker[0] == 'pb':
            b_v, err = check_bool(obj[k], prefix_name)
            if err:
                error += 1

        elif checker[0] == 'l':
            if not isinstance(obj[k], list):
                error += 1
        else:
            log.error(prefix_name +
                      " is not supported in this configuration format")

    return error


def get_nodetype(t):  # t: str -> NodeType
    if t == "host":
        return NodeType.HOST
    elif t == "device":
        return NodeType.DEVICE
    elif t == "async_fifo":
        return NodeType.ASYNC_FIFO
    elif t == "socket_1n":
        return NodeType.SOCKET_1N
    elif t == "socket_m1":
        return NodeType.SOCKET_M1

    log.error("Cannot process type {}".format(t))
    raise


def checkNameExist(name, xbar):  # name: str -> xbar: Xbar -> bool
    return name.lower() in [x.name for x in xbar.nodes]


def isOverlap(range1, range2):  # Tuple[int,int] -> Tuple[int,int] -> bool
    return not (range2[1] < range1[0] or range2[0] > range1[1])


# Tuple[int,int] -> List[Tuple[]] -> bool
def checkAddressOverlap(addr, ranges):
    result = [x for x in ranges if isOverlap(x, addr)]
    return len(result) != 0


def validate(obj: OrderedDict) -> Xbar:  # OrderedDict -> Xbar
    xbar = Xbar()
    xbar.name = obj["name"].lower()
    xbar.clock = obj["clock"].lower()
    xbar.reset = obj["reset"].lower()
    addr_ranges = []

    obj, err = validate_hjson(obj)  # validate Hjson format first
    if err > 0:
        log.error("Hjson structure error")
        return

    # collection of all clocks and resets of this xbar
    xbar.clocks = [clock for clock in obj["clock_connections"].keys()]
    xbar.resets = [reset for reset in obj["reset_connections"].keys()]

    # Nodes
    for nodeobj in obj["nodes"]:

        if checkNameExist(nodeobj["name"], xbar):
            log.error("Duplicated name: %s" % (nodeobj["name"]))
            raise SystemExit("Duplicated name in the configuration")

        clock = nodeobj["clock"].lower() if "clock" in nodeobj.keys(
        ) else xbar.clock

        reset = nodeobj["reset"].lower() if "reset" in nodeobj.keys(
        ) else xbar.reset

        if clock not in xbar.clocks:
            log.error(
                "Clock %s for module %s does not exist in xbar_%s, check xbar hjson"
                % (clock, nodeobj['name'], obj['name']))
            raise SystemExit("Clock does not exist")

        if reset not in xbar.resets:
            log.error(
                "Reset %s for module %s does not exist in xbar_%s, check xbar hjson"
                % (reset, nodeobj['name'], obj['name']))
            raise SystemExit("Reset does not exist")

        node = Node(name=nodeobj["name"].lower(),
                    node_type=get_nodetype(nodeobj["type"].lower()),
                    clock=clock,
                    reset=reset)

        if node.node_type == NodeType.DEVICE:
            node.xbar = nodeobj["xbar"]
            node.addr_range = []

            # Compact the address ranges
            if node.xbar:
                nodeobj["addr_range"] = simplify_addr(nodeobj, obj)

            for addr in nodeobj["addr_range"]:
                address_from = int(addr["base_addr"], 0)
                size = int(addr["size_byte"], 0)
                address_to = address_from + size - 1

                addr_entry = (address_from, address_to)

                if checkAddressOverlap(addr_entry, addr_ranges):
                    log.error(
                        "Address is overlapping. Check the config. Addr(0x%x - 0x%x)"
                        % (addr_entry[0], addr_entry[1]))
                    raise SystemExit("Address overlapping error occurred")

                addr_ranges.append(addr_entry)
                node.addr_range.append(addr_entry)

        if node.node_type in [NodeType.DEVICE, NodeType.HOST
                              ] and "pipeline" in nodeobj:
            node.pipeline = True if nodeobj["pipeline"].lower() in [
                "true", "1"
            ] else False
        else:
            node.pipeline = False
        if node.node_type in [NodeType.DEVICE, NodeType.HOST
                              ] and "pipeline_byp" in nodeobj:
            node.pipeline_byp = True if nodeobj["pipeline_byp"].lower() in [
                "true", "1"
            ] else False
        else:
            node.pipeline_byp = True
        xbar.nodes.append(node)

    # Edge
    for host in obj["connections"].keys():
        # host: [device]
        for device in obj["connections"][host]:
            xbar.connect_nodes(host.lower(), device.lower())

    return xbar


def validate_hjson(obj):
    if "type" not in obj:
        obj["type"] = "xbar"
    if "name" not in obj:
        log.error("Component has no name. Aborting.")
        return None, 1

    component = obj["name"]
    error = check_keys(obj, root, component)

    if error > 0:
        log.error("{} has top level error. Aborting".format(component))
        return None, error
    return obj, 0
