# 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 .item import Edge, Node, NodeType
from .xbar import Xbar

from reggen.validate import val_types, check_int, check_bool, check_ln

# 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)"]
# }
node = {
    'name': 'Node configuration',
    'description': '''
Crossbar node description. It can be host, device, or internal nodes.
''',
    'required': {
        'name': ['s', 'Module instance name'],
        'type': ['s', 'Module type: {"host", "device", "async", "socket_1n", "socket_m1"}'],
    },
    'optional': {
        'clock': ['s', 'main clock of the port'],
        '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'],
        'pipeline': ['pb', 'If true, pipeline is added in front of the port'],
        'pipeline_byp': ['pb', 'Pipeline bypass. If true, '\
                         'request/response are not latched']
    },
    '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'],
        'connections':
        ['g', "List of edge. Key is host, entry in value list is device"],
        '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 not k 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

        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

    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
    xbar = Xbar()
    xbar.name = obj["name"].lower()
    xbar.clock = obj["clock"].lower()

    addr_ranges = []

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

    # Nodes
    for nodeobj in obj["nodes"]:
        clock = nodeobj["clock"].lower() if "clock" in nodeobj.keys(
        ) else xbar.clock

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

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

        if node.node_type == NodeType.DEVICE:
            # Add address obj["base_addr"], obj["size"])
            node.address_from = int(nodeobj["base_addr"], 0)
            size = int(nodeobj["size_byte"], 0)
            node.address_to = node.address_from + size - 1

            addr = (node.address_from, node.address_to)

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

            addr_ranges.append(addr)

        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 not "type" in obj:
        obj["type"] = "xbar"
    if not "name" 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
