"""Provide utilites for converting between FASM and icebox representations.

FASM represents enabling features from a default "empty" configuration.
IceBox documents what each bit does even if should be set by default (unused).

Therefore any differences between ice40 parts are hidden from the FASM
portion. For example IE, REN, and Ram PowerUp are inverted for 1k parts comparted to
all other families.

FASM features attempt to maintain the IceStrom nomenclature.
Exceptions:
 - '/' are replaced with '_' as '/' is not valid for FASM feature name
 - RAM CBITS are combined into READ_MODE and WRITE_MODE FASM features
 - IO configuration bits are combined into SimpleInput and SimpleOut FASM features
"""

from io import StringIO
import re
import unittest
import numpy as np

import icebox
import fasm
from ice40_feature import Feature, IceDbEntry, FasmEntry

# hardcoded permutation
# * https://github.com/YosysHQ/nextpnr/blob/343569105ddf7c97316922774dc4d70d1d4f7c9f/ice40/bitstream.cc#L460-L468
# * https://github.com/cliffordwolf/icestorm/blob/master/icebox/icebox_hlc2asc.py#L925-L936
# * https://github.com/YosysHQ/arachne-pnr/blob/840bdfdeb38809f9f6af4d89dd7b22959b176fdd/src/place.cc#L1573-L1627
LUT_BITS = [4, 14, 15, 5, 6, 16, 17, 7, 3, 13, 12, 2, 1, 11, 10, 0]
LUT_CTRL = {
    "CarryEnable": 8,
    "DffEnable": 9,
    "Set_NoReset": 18,
    "AsyncSetReset": 19
}


def _nibbles_to_bits(line):
    """Convert from icebox hex string for ramdata in asc files to an array of Bool"""

    res = []
    for ch in line:
        res += [xx == "1" for xx in "{:4b}".format(int(ch, 16))]
    res.reverse()
    return res


def _bits_to_nibbles(arr):
    """Convert from array of Bool to icebox hex string used for ramdata in asc files"""

    res = []
    for ii in range(0, len(arr), 4):
        nibble_val = sum(
            (1 << ii) for ii, xx in enumerate(arr[ii:ii + 4]) if xx
        )
        res += "{:x}".format(nibble_val)
    res.reverse()
    return "".join(res)


def _tile_to_array(tile, is_hex=False):
    """Convert text icedb tile to a numpy array"""

    if is_hex:
        array = np.array([_nibbles_to_bits(line) for line in tile], dtype=bool)
    else:
        array = np.array(
            [[int(xx) for xx in line] for line in tile], dtype=bool
        )
    return array


def _array_to_tile(tile_bits, tile, is_hex=False):
    """Convert a numpy array to text icedb tile

    Modifies tile in place to simplify updating of iceconfig
    """
    if is_hex:
        for ii, xx in enumerate(tile_bits):
            tile[ii] = _bits_to_nibbles(xx)
    else:
        for ii, xx in enumerate(tile_bits):
            tile[ii] = tile_bits.shape[1] * "%d" % tuple(xx)


def _lut_to_lc(lut, ctrl):
    """Convert lut and ctrl dict to permuted lc bits"""

    res = 20 * [lut[0]]
    for ii, bit in enumerate(LUT_BITS):
        res[bit] = lut[ii]
    for k, v in ctrl.items():
        res[LUT_CTRL[k]] = v
    return res


def _lc_to_lut(lc):
    """Convert from lc bits to unpermuted lut table and control dict"""

    lut = [lc[val] for val in LUT_BITS]
    ctrl = {k: lc[v] for k, v in LUT_CTRL.items()}
    return lut, ctrl


def _get_feature_bits(tile, cond):
    """Get bitmask and values for the tile from an icebox db entry"""

    bm = np.zeros(tile.shape, dtype=bool)
    bp = np.zeros(tile.shape, dtype=bool)
    for ii in cond:
        neg, x, y = ii
        bm[x][y] = True
        bp[x][y] = neg != "!"
    return bm, bp


def _set_feature_bits(ic, loc, bits):
    """Set bits for a specifc location in an iceconfig"""

    tile = ic.tile(*loc)
    tile_bits = _tile_to_array(tile)
    bm, bv = _get_feature_bits(tile_bits, bits)
    tile_bits[bm] = bv[bm]
    _array_to_tile(tile_bits, tile)


def _get_iceconfig_bits(tile, cond):
    """Get bitmask and values for the tile from an icebox db entry"""

    bm = np.zeros(tile.shape, dtype=bool)
    bp = np.zeros(tile.shape, dtype=bool)
    for ii in cond:
        mm = re.match(r"([\!]?)B([0-9]+)\[([0-9]*)\]", ii)
        neg = mm.group(1)
        inds = [int(mm.group(ii)) for ii in range(2, 4)]
        bm[inds[0]][inds[1]] = 1
        bp[inds[0]][inds[1]] = neg != "!"
    return bm, bp


def _check_iceconfig_entry(tile, entry):
    """Check an entry is set for a tile"""

    bm, bp = _get_iceconfig_bits(tile, entry[0])
    return np.all(bp[bm] == tile[bm])


def _inv_bit_tuple(bit_tuple):
    if bit_tuple[0] == "":
        neg = "!"
    else:
        neg = ""
    return tuple(neg) + bit_tuple[1:]


class FeatureAccumulator(dict):
    """Class to help accumulate iCE40 features for output as FASM file or a FASM DB"""

    def append_feature(self, feature):
        self[feature.to_fasm_entry().feature] = feature

    def append_ice_entry(
            self, tile_type, tile_loc, bits, names, idx, negate=False
    ):

        if negate:
            feature = Feature.from_icedb_entry(
                IceDbEntry(tile_type, tile_loc, bits, names, idx)
            )
            feature.bit_tuples = [
                _inv_bit_tuple(bt) for bt in feature.bit_tuples
            ]
        else:
            feature = Feature.from_icedb_entry(
                IceDbEntry(tile_type, tile_loc, bits, names, idx)
            )

        self.append_feature(feature)
        return feature

    def as_fasm_db(self, outf=StringIO()):
        for key in sorted(self.keys()):
            entry = self[key].to_fasm_entry()
            print(
                "{} {}".format(entry.feature, " ".join(entry.bits)), file=outf
            )
        return outf

    def as_fasm(self, outf=StringIO()):
        for key in sorted(self.keys()):
            print(key, file=outf)
        return outf


def read_ice_db(ic):
    """Read icebox database from iceconfig and construct a dictionary of features"""

    # TODO: undo Hack to invert some specific signals
    device_1k = ic.device == "1k"

    accum = FeatureAccumulator()
    locs = [(x, y) for x in range(ic.max_x + 1) for y in range(ic.max_y + 1)]

    for tile_loc in locs:
        if ic.tile(*tile_loc) is None:
            continue
        tile_type = ic.tile_type(*tile_loc)

        for entry in ic.tile_db(*tile_loc):
            if entry[1].startswith("LC_"):

                lut, ctrl = _lc_to_lut(entry[0])
                for ii, bit in enumerate(lut):
                    names = entry[1:] + ["INIT"]
                    accum.append_ice_entry(
                        tile_type, tile_loc, [bit], names, ii
                    )

                for name, bit in ctrl.items():
                    names = entry[1:] + [name]
                    accum.append_ice_entry(
                        tile_type, tile_loc, [bit], names, None
                    )

            # entries to generate the negated case
            elif (
                    tile_type == "IO" and device_1k and
                (entry[-1].startswith("IE_") or entry[-1].startswith("REN_"))):
                accum.append_ice_entry(
                    tile_type,
                    tile_loc,
                    entry[0],
                    entry[1:],
                    None,
                    negate=True
                )
            elif device_1k and tile_type == "RAMB" and entry[-1] == "PowerUp":
                accum.append_ice_entry(
                    tile_type,
                    tile_loc,
                    entry[0],
                    entry[1:],
                    None,
                    negate=True
                )
            elif tile_type == "RAMT" and entry[-1].startswith("CBIT"):
                matches = re.match(r"CBIT_([0-9]+)", entry[-1])
                assert matches is not None, "Expected 'CBIT_n' received {}".format(
                    entry[-1]
                )

                cbit_offset = matches.group(1)
                cbit_translation = {
                    "0": ("WRITE_MODE", 0),
                    "1": ("WRITE_MODE", 1),
                    "2": ("READ_MODE", 0),
                    "3": ("READ_MODE", 1),
                }
                val = cbit_translation.get(cbit_offset)
                if val is not None:
                    ramb_tile_loc = (tile_loc[0], tile_loc[1] - 1)
                    accum.append_ice_entry(
                        "RAMB", ramb_tile_loc, entry[0], [val[0]], val[1]
                    )
                else:
                    accum.append_ice_entry(
                        tile_type, tile_loc, entry[0], entry[1:], None
                    )
            else:
                accum.append_ice_entry(
                    tile_type, tile_loc, entry[0], entry[1:], None
                )

    # add RAM data entries features
    tile_type = "RAMB"
    for ram_loc in ic.ramb_tiles:
        for i in range(16):
            feature_name = "INIT{:X}".format(i)
            for j in range(256):
                bit = "B{}[{}]".format(i, j)
                accum.append_ice_entry(
                    tile_type, ram_loc, [bit], [feature_name], j
                )

    # TODO: extra bits?

    return accum


def _iceboxdb_to_fasmdb(ic, outf=StringIO()):
    """Read in an icebox config and output the exhaustive list of bits with fasm compatible names

    expand RAM and LUT INIT bits
    """

    fasmdb = read_ice_db(ic)
    return fasmdb.as_fasm_db(outf)


def generate_fasm_db(outf, device):
    """Generate FASM style DB for a ice40 device"""

    ic = icebox.iceconfig()
    init_method_name = "setup_empty_{}".format(device.lower()[2:])
    assert hasattr(
        ic, init_method_name
    ), "no icebox method to init empty device"
    getattr(ic, init_method_name)()

    return _iceboxdb_to_fasmdb(ic, outf)


def asc_to_fasm(filename, outf=StringIO()):
    """Generate a fasm output from an asc"""

    ic = icebox.iceconfig()
    ic.read_file(filename)

    return iceconfig_to_fasm(ic, outf)


def iceconfig_to_fasm(ic, outf=StringIO()):
    """Read iceconfig and generate FASM features.

    Useful for generating FASM from ASC file.
    """

    # TODO: undo Hack to invert some specific signals
    device_1k = ic.device == "1k"

    accum = FeatureAccumulator()

    locs = [(x, y) for x in range(ic.max_x + 1) for y in range(ic.max_y + 1)]
    for tile_loc in locs:
        bits = ic.tile(*tile_loc)
        if bits is None:
            continue
        tile_bits = _tile_to_array(bits)
        tile_type = ic.tile_type(*tile_loc)

        for entry in ic.tile_db(*tile_loc):
            # LC_ entries are treated differently as it's not a match, but a pattern
            if entry[1].startswith("LC_"):
                bm, _ = _get_iceconfig_bits(tile_bits, entry[0])
                bits = tile_bits[bm]
                if np.any(bits):
                    lut, ctrl = _lc_to_lut(bits)
                    for ii, bit in enumerate(lut):
                        if bit:
                            names = entry[1:] + ["INIT"]
                            accum.append_ice_entry(
                                tile_type, tile_loc, [], names, ii
                            )

                    for name, bit in ctrl.items():
                        if bit:
                            names = entry[1:] + [name]
                            accum.append_ice_entry(
                                tile_type, tile_loc, [], names, None
                            )

            elif (
                    tile_type == "IO" and device_1k and
                (entry[-1].startswith("IE_") or entry[-1].startswith("REN_"))):
                accum.append_ice_entry(
                    tile_type,
                    tile_loc,
                    entry[0],
                    entry[1:],
                    None,
                    negate=True
                )
            elif device_1k and tile_type == "RAMB" and entry[-1] == "PowerUp":
                accum.append_ice_entry(
                    tile_type,
                    tile_loc,
                    entry[0],
                    entry[1:],
                    None,
                    negate=True
                )
            elif tile_type == "RAMT" and entry[-1].startswith("CBIT"):
                matches = re.match(r"CBIT_([0-9]+)", entry[-1])
                assert matches is not None, "Expected 'CBIT_n' received {}".format(
                    entry[-1]
                )

                cbit_offset = matches.group(1)
                cbit_translation = {
                    "0": ("WRITE_MODE", 0),
                    "1": ("WRITE_MODE", 1),
                    "2": ("READ_MODE", 0),
                    "3": ("READ_MODE", 1),
                }
                val = cbit_translation.get(cbit_offset)
                if val is not None:
                    ramb_tile_loc = (tile_loc[0], tile_loc[1] - 1)
                    accum.append_ice_entry(
                        "RAMB", ramb_tile_loc, entry[0], [val[0]], val[1]
                    )
                else:
                    accum.append_ice_entry(
                        tile_type, tile_loc, entry[0], entry[1:], None
                    )

            else:
                if _check_iceconfig_entry(tile_bits, entry):
                    accum.append_ice_entry(
                        tile_type, tile_loc, entry[0], entry[1:], None
                    )

    # ram data
    for tile_loc, hexd in ic.ram_data.items():
        tile_bits = _tile_to_array(hexd, is_hex=True)
        tile_type = "RAMB"

        for x, y in zip(*np.where(tile_bits)):
            feature_name = "INIT{:X}".format(x)
            bit = "B{}[{}]".format(x, y)
            entry = [[bit], feature_name]
            feature = Feature.from_icedb_entry(
                IceDbEntry(tile_type, tile_loc, entry[0], entry[1:], y)
            )
            print(feature.to_fasm_entry().feature, file=outf)

    # TODO: extra_bits

    return accum.as_fasm(outf)


def fasm_to_asc(in_fasm, outf, device):
    """Convert an FASM input to an ASC file

    Set input enable defaults, RAM powerup, and enables all ColBufCtrl (until modeled in VPR see: #464)
    """

    ic = icebox.iceconfig()

    init_method_name = "setup_empty_{}".format(device.lower()[2:])
    assert hasattr(
        ic, init_method_name
    ), "no icebox method to init empty device"
    getattr(ic, init_method_name)()

    device_1k = ic.device == "1k"

    fasmdb = read_ice_db(ic)
    # TODO: upstream init "default" bitstream
    locs = [(x, y) for x in range(ic.max_x + 1) for y in range(ic.max_y + 1)]
    for tile_loc in locs:
        tile = ic.tile(*tile_loc)
        if tile is None:
            continue
        db = ic.tile_db(*tile_loc)
        tile_type = ic.tile_type(*tile_loc)
        for entry in db:
            if (device_1k and
                ((tile_type == "IO" and entry[-1] in ["IE_0", "IE_1"]) or
                 (tile_type == "RAMB" and entry[-1] == "PowerUp"))
                    or (entry[-2] == "ColBufCtrl")):
                tile_bits = _tile_to_array(tile)
                tile_type = ic.tile_type(*tile_loc)
                bm, bv = _get_iceconfig_bits(tile_bits, entry[0])
                tile_bits[bm] = bv[bm]
                _array_to_tile(tile_bits, tile)

    missing_features = []
    for line in fasm.parse_fasm_string(in_fasm.read()):
        if not line.set_feature:
            continue

        line_strs = tuple(fasm.fasm_line_to_string(line))
        assert len(line_strs) == 1

        feature = Feature.from_fasm_entry(
            FasmEntry(line.set_feature.feature, [])
        )

        def find_ieren(ic, loc, iob):
            tmap = [
                xx[3:]
                for xx in ic.ieren_db()
                if xx[:3] == (tuple(loc) + (iob, ))
            ]
            assert len(tmap) < 2, "expected 1 IEREN_DB entry found {}".format(
                len(tmap)
            )

            if len(tmap) == 0:
                print("no ieren found for {}".format((tile_loc + (iob, ))))
                return
            return tmap[0]

        # fix up for IO
        if feature.parts[-1] == "SimpleInput":
            iob = int(feature.parts[-2][-1])
            new_ieren = find_ieren(ic, feature.loc, iob)

            feature.parts[-1] = "PINTYPE_0"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)

            feature.loc = new_ieren[:2]
            feature.parts[-2] = "IoCtrl"
            feature.parts[-1] = "IE_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            feature.parts[-1] = "REN_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            continue

        if feature.parts[-1] == "SimpleOutput":
            iob = int(feature.parts[-2][-1])
            new_ieren = find_ieren(ic, feature.loc, iob)

            feature.parts[-1] = "PINTYPE_3"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            feature.parts[-1] = "PINTYPE_4"
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)

            feature.loc = new_ieren[:2]
            feature.parts[-2] = "IoCtrl"
            feature.parts[-1] = "REN_{}".format(new_ieren[2])
            db_entry = fasmdb[feature.to_fasm_entry().feature]
            _set_feature_bits(ic, db_entry.loc, db_entry.bit_tuples)
            continue

        ## special case for RAM INIT values
        tile_type, loc = feature.tile_type, feature.loc
        if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"):
            tloc = tuple(loc)
            if tloc not in ic.ram_data:
                ic.ram_data[tloc] = [64 * "0" for _ in range(16)]
            tile = ic.ram_data[tloc]
            tile_bits = _tile_to_array(tile, is_hex=True)
        elif tile_type == "RAMB" and feature.parts[-1].endswith("_MODE"):
            # hack to force modes to the RAMT
            tile = ic.tile(loc[0], loc[1] + 1)
            tile_bits = _tile_to_array(tile)
        else:
            tile = ic.tile(*loc)
            tile_bits = _tile_to_array(tile)

        # lookup feature and convert
        for canonical_feature in fasm.canonical_features(line.set_feature):
            key = fasm.set_feature_to_str(canonical_feature)
            feature = fasmdb[key]
            bm, bv = _get_feature_bits(tile_bits, feature.bit_tuples)

            tile_bits[bm] = bv[bm]

        if tile_type == "RAMB" and feature.parts[-1].startswith("INIT"):
            _array_to_tile(tile_bits, tile, is_hex=True)
        else:
            _array_to_tile(tile_bits, tile)

    # TODO: would be nice to upstream a way to write to non-files
    ic.write_file(outf.name)


if __name__ == "__main__":
    import argparse
    import sys

    parser = argparse.ArgumentParser(description="Dump FASM DB from icebox")
    parser.add_argument("device", help="Device type (eg lp1k, hx8k)")
    parser.add_argument(
        "--output",
        help="Output file",
        type=argparse.FileType("w"),
        default=sys.stdout
    )
    args = parser.parse_args()

    generate_fasm_db(args.output, args.device)
