# 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
import re
import sys
from collections import OrderedDict
from copy import deepcopy
from pathlib import Path
from typing import Dict, List, Optional, Tuple

import hjson
from reggen.ip_block import IpBlock

# Ignore flake8 warning as the function is used in the template
# disable isort formating, as conflicting with flake8
from .intermodule import find_otherside_modules  # noqa : F401 # isort:skip
from .intermodule import im_portname, im_defname, im_netname # noqa : F401 # isort:skip
from .intermodule import get_direction # noqa : F401 # isort:skip
from .intermodule import get_dangling_im_def # noqa : F401 # isort:skip


class Name:
    """
    We often need to format names in specific ways; this class does so.

    To simplify parsing and reassembling of name strings, this class
    stores the name parts as a canonical list of strings internally
    (in self.parts).

    The "from_*" functions parse and split a name string into the canonical
    list, whereas the "as_*" functions reassemble the canonical list in the
    format specified.

    For example, ex = Name.from_snake_case("example_name") gets split into
    ["example", "name"] internally, and ex.as_camel_case() reassembles this
    internal representation into "ExampleName".
    """
    def __add__(self, other):
        return Name(self.parts + other.parts)

    @staticmethod
    def from_snake_case(input: str) -> 'Name':
        return Name(input.split("_"))

    def __init__(self, parts: List[str]):
        self.parts = parts
        for p in parts:
            assert len(p) > 0, "cannot add zero-length name piece"

    def as_snake_case(self) -> str:
        return "_".join([p.lower() for p in self.parts])

    def as_camel_case(self) -> str:
        out = ""
        for p in self.parts:
            # If we're about to join two parts which would introduce adjacent
            # numbers, put an underscore between them.
            if out[-1:].isnumeric() and p[:1].isnumeric():
                out += "_" + p
            else:
                out += p.capitalize()
        return out

    def as_c_define(self) -> str:
        return "_".join([p.upper() for p in self.parts])

    def as_c_enum(self) -> str:
        return "k" + self.as_camel_case()

    def as_c_type(self) -> str:
        return self.as_snake_case() + "_t"

    def remove_part(self, part_to_remove: str) -> "Name":
        return Name([p for p in self.parts if p != part_to_remove])


def is_ipcfg(ip: Path) -> bool:  # return bool
    log.info("IP Path: %s" % repr(ip))
    ip_name = ip.parents[1].name
    hjson_name = ip.name

    log.info("IP Name(%s) and HJSON name (%s)" % (ip_name, hjson_name))

    if ip_name + ".hjson" == hjson_name or ip_name + "_reg.hjson" == hjson_name:
        return True
    return False


def search_ips(ip_path):  # return list of config files
    # list the every Hjson file
    p = ip_path.glob('*/data/*.hjson')

    # filter only ip_name/data/ip_name{_reg|''}.hjson
    ips = [x for x in p if is_ipcfg(x)]

    log.info("Filtered-in IP files: %s" % repr(ips))
    return ips


def is_xbarcfg(xbar_obj):
    if "type" in xbar_obj and xbar_obj["type"] == "xbar":
        return True

    return False


def get_hjsonobj_xbars(xbar_path):
    """ Search crossbars Hjson files from given path.

    Search every Hjson in the directory and check Hjson type.
    It could be type: "top" or type: "xbar"
    returns [(name, obj), ... ]
    """
    p = xbar_path.glob('*.hjson')
    try:
        xbar_objs = [
            hjson.load(x.open('r'),
                       use_decimal=True,
                       object_pairs_hook=OrderedDict) for x in p
        ]
    except ValueError:
        raise SystemExit(sys.exc_info()[1])

    xbar_objs = [x for x in xbar_objs if is_xbarcfg(x)]

    return xbar_objs


def get_module_by_name(top, name):
    """Search in top["module"] by name
    """
    module = None
    for m in top["module"]:
        if m["name"] == name:
            module = m
            break

    return module


def intersignal_to_signalname(top, m_name, s_name) -> str:

    # TODO: Find the signal in the `inter_module_list` and get the correct signal name

    return "{m_name}_{s_name}".format(m_name=m_name, s_name=s_name)


def get_package_name_by_intermodule_signal(top, struct) -> str:
    """Search inter-module signal package with the struct name

    For instance, if `flash_ctrl` has inter-module signal package,
    this function returns the package name
    """
    instances = top["module"] + top["memory"]

    intermodule_instances = [
        x["inter_signal_list"] for x in instances if "inter_signal_list" in x
    ]

    for m in intermodule_instances:
        if m["name"] == struct and "package" in m:
            return m["package"]
    return ""


def get_signal_by_name(module, name):
    """Return the signal struct with the type input/output/inout
    """
    result = None
    for s in module["available_input_list"] + module[
            "available_output_list"] + module["available_inout_list"]:
        if s["name"] == name:
            result = s
            break

    return result


def add_module_prefix_to_signal(signal, module):
    """Add module prefix to module signal format { name: "sig_name", width: NN }
    """
    result = deepcopy(signal)

    if "name" not in signal:
        raise SystemExit("signal {} doesn't have name field".format(signal))

    result["name"] = module + "_" + signal["name"]
    result["module_name"] = module

    return result


def get_ms_name(name):
    """Split module_name.signal_name to module_name , signal_name
    """

    tokens = name.split('.')

    if len(tokens) == 0:
        raise SystemExit("This to be catched in validate.py")

    module = tokens[0]
    signal = None
    if len(tokens) == 2:
        signal = tokens[1]

    return module, signal


def parse_pad_field(padstr):
    """Parse PadName[NN...NN] or PadName[NN] or just PadName
    """
    match = re.match(r'^([A-Za-z0-9_]+)(\[([0-9]+)(\.\.([0-9]+))?\]|)', padstr)
    return match.group(1), match.group(3), match.group(5)


def get_pad_list(padstr):
    pads = []

    pad, first, last = parse_pad_field(padstr)
    if first is None:
        first = 0
        last = 0
    elif last is None:
        last = first
    first = int(first, 0)
    last = int(last, 0)
    # width = first - last + 1

    for p in range(first, last + 1):
        pads.append(OrderedDict([("name", pad), ("index", p)]))

    return pads


# Template functions
def ljust(x, width):
    return "{:<{width}}".format(x, width=width)


def bitarray(d, width):
    """Print Systemverilog bit array

    @param d the bit width of the signal
    @param width max character width of the signal group

    For instance, if width is 4, the max d value in the signal group could be
    9999. If d is 2, then this function pads 3 spaces at the end of the bit
    slice.

    "[1:0]   " <- d:=2, width=4
    "[9999:0]" <- max d-1 value

    If d is 1, it means array slice isn't necessary. So it returns empty spaces
    """

    if d <= 0:
        log.error("lib.bitarray: Given value {} is smaller than 1".format(d))
        raise ValueError
    if d == 1:
        return " " * (width + 4)  # [x:0] needs 4 more space than char_width

    out = "[{}:0]".format(d - 1)
    return out + (" " * (width - len(str(d))))


def parameterize(text):
    """Return the value wrapping with quote if not integer nor bits
    """
    if re.match(r'(\d+\'[hdb]\s*[0-9a-f_A-F]+|[0-9]+)', text) is None:
        return "\"{}\"".format(text)

    return text


def index(i: int) -> str:
    """Return index if it is not -1
    """
    return "[{}]".format(i) if i != -1 else ""


def get_clk_name(clk):
    """Return the appropriate clk name
    """
    if clk == 'main':
        return 'clk_i'
    else:
        return "clk_{}_i".format(clk)


def is_shadowed_port(block: IpBlock, port: str) -> bool:
    """Return boolean indication whether a port is a shadow reset port
    """
    shadowed_port = block.clocking.primary.reset if block.has_shadowed_reg() \
        else None

    return port == shadowed_port


def shadow_name(name: str) -> str:
    """Return the appropriate shadow reset name based on port name
    """
    match = re.match(r'^rst_([A-Za-z0-9_]+)_ni?', name)
    if match:
        return f'rst_{match.group(1)}_shadowed_ni'
    else:
        return 'rst_shadowed_ni'


def get_reset_path(top: object, reset: str, shadow_sel: bool = False):
    """Return the appropriate reset path given name
    """
    return top['resets'].get_path(reset['name'], reset['domain'], shadow_sel)


def get_reset_lpg_path(top: object, reset: str, shadow_sel: bool = False, domain: bool = None):
    """Return the appropriate LPG reset path given name
    """
    if domain is not None:
        return top['resets'].get_lpg_path(reset['name'], domain, shadow_sel)
    else:
        return top['resets'].get_lpg_path(reset['name'], reset['domain'], shadow_sel)


def get_unused_resets(top):
    """Return dict of unused resets and associated domain
    """
    return top['resets'].get_unused_resets(top['power']['domains'])


def get_templated_modules(top):
    """Returns list of all templated modules.
    """
    return [m['type'] for m in top['module'] if is_templated(m)]


def get_ipgen_modules(top):
    """Returns list of all ipgen modules.
    """
    return [m['type'] for m in top['module'] if is_ipgen(m)]


def get_top_reggen_modules(top):
    """Returns list of all ipgen modules.
    """
    return [m['type'] for m in top['module'] if is_top_reggen(m)]


def is_templated(module):
    """Returns an indication where a particular module is templated
    """
    return module.get('attr') in ["templated"]


def is_ipgen(module):
    """Returns an indication where a particular module is ipgen
    """
    return module.get('attr') in ["ipgen"]


def is_top_reggen(module):
    """Returns an indication where a particular module is NOT templated
       and requires top level specific reggen
    """
    return module.get('attr') in ["reggen_top", "reggen_only"]


def is_reggen_only(module):
    """Returns an indication where a particular module is NOT templated,
       requires top level specific reggen and is NOT instantiated in the
       top
    """
    return module.get('attr') == "reggen_only"


def is_inst(module):
    """Returns an indication where a particular module should be instantiated
       in the top level
    """
    top_level_module = False
    top_level_mem = False

    if "attr" not in module:
        top_level_module = True
    elif module["attr"] in ["normal", "templated", "ipgen", "reggen_top"]:
        top_level_module = True
    elif module["attr"] in ["reggen_only"]:
        top_level_module = False
    else:
        raise ValueError('Attribute {} in {} is not valid'
                         .format(module['attr'], module['name']))

    if module['type'] in ['rom', 'ram_1p_scr', 'eflash']:
        top_level_mem = True

    return top_level_mem or top_level_module


def get_base_and_size(name_to_block: Dict[str, IpBlock],
                      inst: Dict[str, object],
                      ifname: Optional[str]) -> Tuple[int, int]:
    min_device_spacing = 0x1000

    block = name_to_block.get(inst['type'])
    if block is None:
        # If inst isn't the instantiation of a block, it came from some memory.
        # Memories have their sizes defined, so we can just look it up there.
        bytes_used = int(inst['size'], 0)

        # Memories don't have multiple or named interfaces, so this will only
        # work if ifname is None.
        assert ifname is None
        base_addr = inst['base_addr']

    else:
        # If inst is the instantiation of some block, find the register block
        # that corresponds to ifname
        rb = block.reg_blocks.get(ifname)
        if rb is None:
            raise RuntimeError(
                'Cannot connect to non-existent {} device interface '
                'on {!r} (an instance of the {!r} block).'
                .format('default' if ifname is None else repr(ifname),
                        inst['name'], block.name))
        else:
            bytes_used = 1 << rb.get_addr_width()

        base_addr = inst['base_addrs'][ifname]

        # If an instance has a nonempty "memory" field, take the memory
        # size configuration from there.
        if "memory" in inst:
            if ifname in inst["memory"]:
                memory_size = int(inst["memory"][ifname]["size"], 0)
                if bytes_used > memory_size:
                    raise RuntimeError(
                        'Memory region on {} device interface '
                        'on {!r} (an instance of the {!r} block) '
                        'is smaller than the corresponding register block.'
                        .format('default' if ifname is None else repr(ifname),
                                inst['name'], block.name))

                bytes_used = memory_size

    # Round up to min_device_spacing if necessary
    size_byte = max(bytes_used, min_device_spacing)

    if isinstance(base_addr, str):
        base_addr = int(base_addr, 0)
    else:
        assert isinstance(base_addr, int)

    return (base_addr, size_byte)


def get_io_enum_literal(sig: Dict, prefix: str) -> str:
    """Returns the DIO pin enum literal with value assignment"""
    name = Name.from_snake_case(prefix) + Name.from_snake_case(sig["name"])
    # In this case, the signal is a multibit signal, and hence
    # we have to make the signal index part of the parameter
    # name to uniquify it.
    if sig['width'] > 1:
        name += Name([str(sig['idx'])])
    return name.as_camel_case()


def make_bit_concatenation(sig_name: str,
                           indices: List[int],
                           end_indent: int) -> str:
    '''Return SV code for concatenating certain indices from a signal

    sig_name is the name of the signal and indices is a non-empty list of the
    indices to use, MSB first. So

      make_bit_concatenation("foo", [0, 100, 20])

    should give

      {foo[0], foo[100], foo[20]}

    Adjacent bits turn into a range select. For example:

      make_bit_concatenation("foo", [0, 1, 2])

    should give

      foo[0:2]

    If there are multiple ranges, they are printed one to a line. end_indent
    gives the indentation of the closing brace and the range selects in between
    get indented to end_indent + 2.

    '''
    assert 0 <= end_indent

    ranges = []
    cur_range_start = indices[0]
    cur_range_end = indices[0]
    for idx in indices[1:]:
        if idx == cur_range_end + 1 and cur_range_start <= cur_range_end:
            cur_range_end += 1
            continue
        if idx == cur_range_end - 1 and cur_range_start >= cur_range_end:
            cur_range_end -= 1
            continue
        ranges.append((cur_range_start, cur_range_end))
        cur_range_start = idx
        cur_range_end = idx
    ranges.append((cur_range_start, cur_range_end))

    items = []
    for range_start, range_end in ranges:
        if range_start == range_end:
            select = str(range_start)
        else:
            select = '{}:{}'.format(range_start, range_end)
        items.append('{}[{}]'.format(sig_name, select))

    if len(items) == 1:
        return items[0]

    item_indent = '\n' + (' ' * (end_indent + 2))

    acc = ['{', item_indent, items[0]]
    for item in items[1:]:
        acc += [',', item_indent, item]
    acc += ['\n', ' ' * end_indent, '}']
    return ''.join(acc)


def is_rom_ctrl(modules):
    '''Return true if rom_ctrl (and thus boot-up rom integrity checking)
       exists in the design
    '''
    for m in modules:
        if m['type'] == 'rom_ctrl':
            return True

    return False


def is_lc_ctrl(modules):
    '''Return true if lc_ctrl exists in the design
    '''
    for m in modules:
        if m['type'] == 'lc_ctrl':
            return True

    return False
