from collections import namedtuple
from utils import bitstream
from utils.grid import BlockType
import enum
import functools


class PsuedoPipType(enum.Enum):
    ALWAYS = 'always'
    DEFAULT = 'default'
    HINT = 'hint'


def read_ppips(f):
    ppips = {}

    for l in f:
        l = l.strip()
        if not l:
            continue

        feature, ppip_type = l.split(' ')

        ppips[feature] = PsuedoPipType(ppip_type)

    return ppips


Bit = namedtuple('Bit', 'word_column word_bit isset')


def parsebit(val):
    '''Return "!012_23" => (12, 23, False)'''
    isset = True
    # Default is 0. Skip explicit call outs
    if val[0] == '!':
        isset = False
        val = val[1:]
    # 28_05 => 28, 05
    seg_word_column, word_bit_n = val.split('_')

    return Bit(
        word_column=int(seg_word_column),
        word_bit=int(word_bit_n),
        isset=isset,
    )


def read_segbits(f):
    segbits = {}

    for l in f:
        # CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14
        l = l.strip()

        if not l:
            continue

        parts = l.split(' ')

        assert len(parts) > 1

        segbits[parts[0]] = [parsebit(val) for val in parts[1:]]

    return segbits


class TileSegbits(object):
    def __init__(self, tile_db):
        self.segbits = {}
        self.ppips = {}
        self.feature_addresses = {}

        if tile_db.ppips is not None:
            with open(tile_db.ppips) as f:
                self.ppips = read_ppips(f)

        if tile_db.segbits is not None:
            with open(tile_db.segbits) as f:
                self.segbits[BlockType.CLB_IO_CLK] = read_segbits(f)

        if tile_db.block_ram_segbits is not None:
            with open(tile_db.block_ram_segbits) as f:
                self.segbits[BlockType.BLOCK_RAM] = read_segbits(f)

        for block_type in self.segbits:
            for feature in self.segbits[block_type]:
                sidx = feature.rfind('[')
                eidx = feature.rfind(']')

                if sidx != -1:
                    assert eidx != -1

                    base_feature = feature[:sidx]

                    if base_feature not in self.feature_addresses:
                        self.feature_addresses[base_feature] = {}

                    self.feature_addresses[base_feature][int(
                        feature[sidx + 1:eidx])] = (block_type, feature)

    def match_bitdata(self, block_type, bits, bitdata, match_filter=None):
        """ Return matching features for tile bits data (grid.Bits) and bitdata.

        See bitstream.load_bitdata for details on bitdata structure.

        """

        if block_type not in self.segbits:
            return

        for feature, segbit in self.segbits[block_type].items():
            match = True
            skip = False
            for query_bit in segbit:
                if match_filter is not None and not match_filter(block_type,
                                                                 query_bit):
                    skip = True
                    break

                frame = bits.base_address + query_bit.word_column
                bitidx = bits.offset * bitstream.WORD_SIZE_BITS + query_bit.word_bit

                if frame not in bitdata:
                    match = not query_bit.isset
                    if match:
                        continue
                    else:
                        break

                found_bit = bitidx in bitdata[frame][1]
                match = found_bit == query_bit.isset

                if not match:
                    break

            if not match or skip:
                continue

            def inner():
                for query_bit in segbit:
                    if query_bit.isset:
                        frame = bits.base_address + query_bit.word_column
                        bitidx = bits.offset * bitstream.WORD_SIZE_BITS + query_bit.word_bit
                        yield (frame, bitidx)

            yield (tuple(inner()), feature)

    def map_bit_to_frame(self, block_type, bits, bit):
        """ Convert bit from segbit to frame data. """
        return Bit(
            word_column=bits.base_address + bit.word_column,
            word_bit=bits.offset * bitstream.WORD_SIZE_BITS + bit.word_bit,
            isset=bit.isset,
        )

    def feature_to_bits(self, bits_map, feature, address=0):
        if feature in self.ppips:
            return

        for block_type in self.segbits:
            if address == 0 and feature in self.segbits[block_type]:
                for bit in self.segbits[block_type][feature]:
                    yield block_type, self.map_bit_to_frame(
                        block_type, bits_map[block_type], bit)
                return

        block_type, feature = self.feature_addresses[feature][address]
        for bit in self.segbits[block_type][feature]:
            yield block_type, self.map_bit_to_frame(
                block_type, bits_map[block_type], bit)
