""" Database files available for a tile type. """
from collections import namedtuple
import json
from utils import lib
from utils.timing import fast_slow_tuple_to_corners, RcElement

TileDbs = namedtuple(
    'TileDbs', 'segbits block_ram_segbits ppips mask tile_type')


class OutPinTiming(namedtuple('OutPinTiming', 'delays drive_resistance')):
    """ Timing for site output pins.

    Attributes
    ----------
    delays : dicts of PvtCorner to IntristicDelay
        Intristic delay of output pin.
    drive_resistance : float
        Resistance of drive output pin (milliOhms).

    """
    pass


class InPinTiming(namedtuple('InPinTiming', 'delays capacitance')):
    """ Timing for site input pins.

    Attributes
    ----------
    delays : dicts of PvtCorner to IntristicDelay
        Intristic delay of input pin.
    capacitance : float
        Capacitance of input pints (microFarads).

    """
    pass


class PipTiming(namedtuple('PipTiming',
                           'delays drive_resistance internal_capacitance')):
    """ Timing for pips.

    Attributes
    ----------
    delays : dicts of PvtCorner to IntristicDelay
        Intristic delay of pip.
    internal_capacitance : float
        Capacitance (microFarads) of pip (which is only seen if pip is used).
    drive_resistance : float
        Resistance of drive output pin (milliOhms).

    """
    pass


class Pip(namedtuple(
        'Pip',
    ('name', 'net_to', 'net_from', 'can_invert', 'is_directional', 'is_pseudo',
     'is_pass_transistor', 'timing', 'backward_timing'))):
    """ Pip information.

    Attributes
    ----------

    name : str
        Name of pip
    net_to : str
        Name of output tile wire when pip is unidirectional.
    net_from: str
        Name of input tile wire when pip is unidirectional.
    can_invert : bool
        Can this pip invert the signal.
    is_directional : bool
        True if this pip is unidirectional, False if this pip is
        unidirectional.
    is_pseudo : bool
        True if this pip is mark as a pseudo-pip.
    is_pass_transistor : bool
        True if this pip is non-isolating.
    timing : PipTiming
        Timing used when connecting net_from to net_to.  This is the only
        timing used when a pip is unidirectional.

        May be None if timing information is not present in the database.
    backward_timing : PipTiming
        Timing used when connecting net_to to net_from.  This is only used
        if the pip is bidirectional.

        May be None if timing information is not present in the database.

    """
    pass


class Site(namedtuple('Site', 'name prefix x y type site_pins')):
    """ Represents an instance of a site within a tile.

    Attributes
    ----------
    name : str
        Name of site within tile, instance specific.
    prefix : str
        Prefix of site naming in Xilinx parlance.
    type : str
        What type of slice this instance presents.
    site_pins : list of SitePin
        Instaces of site pins within this site and tile.  This is an tuple of
        SitePin tuples, and is specific to this instance of the site within
        the tile.

    """


class SitePin(namedtuple('SitePin', 'name wire timing')):
    """ Tuple representing a site pin within a tile.

    Sites are generic based on type, however sites are instanced
    within a tile 1 or more times.  The SitePin contains both site type generic
    information and tile type specific information.

    Attributes
    ----------
    name : str
        Site type specific name.  This name is expected to be the same for
        all sites of the same type.
    wire : str
        Wire name within the tile.  This name is site instance specific.
    timing : Either InPinTiming or OutPinTiming
        Timing of site pin. May be None if database lacks timing information.

    """


WireInfo = namedtuple('WireInfo', 'pips sites')

# Conversion factor from database to internal units.
RESISTANCE_FACTOR = 1e3
CAPACITANCE_FACTOR = 1e3


def get_pip_timing(pip_timing_json):
    """ Convert pip_timing_json JSON into PipTiming object.

    Returns
    -------
    If timing information is not present for this pip, returns None.
    If timing information is present, returns PipTiming.  Some fields may be
    None if the pip type lacks that field.

    """

    if pip_timing_json is None:
        return None

    delays = None

    if pip_timing_json.get('delay') is not None:
        delays = fast_slow_tuple_to_corners(pip_timing_json.get('delay'))

    in_cap = pip_timing_json.get('in_cap')
    if in_cap is not None:
        in_cap = float(in_cap) / CAPACITANCE_FACTOR
    else:
        in_cap = 0

    res = pip_timing_json.get('res')
    if res is not None:
        res = float(res) / RESISTANCE_FACTOR
    else:
        res = 0

    return PipTiming(
        delays=delays,
        drive_resistance=res,
        internal_capacitance=in_cap,
    )


def get_site_pin_timing(site_pin_info):
    """ Convert site_pin_info JSON into InPinTiming or OutPinTiming object.

    Returns
    -------
    If timing information is not present for this site pin, returns None.
    If this is an output pin, returns OutPinTiming.
    If this is an input pin, returns InPinTiming.

    """
    if isinstance(site_pin_info, str):
        return site_pin_info, None

    wire = site_pin_info['wire']

    if 'delay' not in site_pin_info:
        return None

    delays = fast_slow_tuple_to_corners(site_pin_info['delay'])

    if 'cap' in site_pin_info:
        assert 'res' not in site_pin_info
        return wire, InPinTiming(
            delays=delays,
            capacitance=float(site_pin_info['cap']) / CAPACITANCE_FACTOR,
        )
    else:
        assert 'res' in site_pin_info
        return wire, OutPinTiming(
            delays=delays,
            drive_resistance=float(site_pin_info['res']) / RESISTANCE_FACTOR,
        )


def get_wires(wires):
    """ Converts database input to dictionary of tile wires to wire timing.

    Returns dictionary of tile wire name to RcElement or None. """

    if isinstance(wires, list):
        # Handle old database gracefully.
        return {wire: None for wire in wires}

    output = {}

    for wire, rc_json in wires.items():
        if rc_json is None:
            output[wire] = RcElement(
                resistance=0,
                capacitance=0,
            )
        else:
            output[wire] = RcElement(
                resistance=float(rc_json['res']) / RESISTANCE_FACTOR,
                capacitance=float(rc_json['cap']) / CAPACITANCE_FACTOR,
            )

    return output


def is_pass_transistor(pip_json):
    """ Returns boolean if pip JSON indicates pip is a pass transistor.

    Always returns False if database lacks this information.
    """
    if 'is_pass_transistor' in pip_json:
        return bool(int(pip_json['is_pass_transistor']))
    else:
        return False


class Tile(object):
    """ Provides abstration of a tile in the database. """

    def __init__(self, tilename, tile_dbs):
        self.tilename = tilename
        self.tilename_upper = self.tilename.upper()
        self.tile_dbs = tile_dbs

        self.wires = None
        self.sites = None
        self.pips = None
        self.pips_by_name = {}

        def yield_sites(sites):
            for site in sites:
                site_pins = []
                for name, site_pin_info in site['site_pins'].items():
                    if site_pin_info is not None:
                        wire, timing = get_site_pin_timing(site_pin_info)
                        site_pins.append(
                            SitePin(
                                name=name,
                                wire=wire,
                                timing=timing,
                            ))
                    else:
                        site_pins.append(
                            SitePin(
                                name=name,
                                wire=None,
                                timing=None,
                            ))

                yield Site(
                    name=site['name'],
                    prefix=site['prefix'],
                    type=site['type'],
                    x=site['x_coord'],
                    y=site['y_coord'],
                    site_pins=site_pins,
                )

        def yield_pips(pips):
            for name, pip in pips.items():
                yield Pip(
                    name=name,
                    net_to=pip['dst_wire'],
                    net_from=pip['src_wire'],
                    can_invert=bool(int(pip['can_invert'])),
                    is_directional=bool(int(pip['is_directional'])),
                    is_pseudo=bool(int(pip['is_pseudo'])),
                    is_pass_transistor=is_pass_transistor(pip),
                    timing=get_pip_timing(pip.get('src_to_dst')),
                    backward_timing=get_pip_timing(pip.get('dst_to_src')),
                )

        with open(self.tile_dbs.tile_type) as f:
            tile_type = json.load(f)
            assert self.tilename_upper == tile_type['tile_type']
            self.wires = get_wires(tile_type['wires'])
            self.sites = tuple(yield_sites(tile_type['sites']))
            self.pips = tuple(yield_pips(tile_type['pips']))

        self.wire_info = {}

    def get_wires(self):
        """Returns a set of wire names present in this tile."""
        return self.wires

    def get_sites(self):
        """ Returns tuple of Site namedtuple's present in this tile. """
        return self.sites

    def get_pips(self):
        """ Returns tuple of Pip namedtuple's representing the PIPs in this tile.
    """
        return self.pips

    def get_pip_by_name(self, name):
        if len(self.pips_by_name) == 0:
            for pip in self.pips:
                self.pips_by_name[pip.name] = pip

        return self.pips_by_name[name]

    def get_wire_info(self, target_wire, allow_pseudo=False):
        if len(self.wire_info) == 0:
            for wire in self.wires:
                pips = list()
                sites = list()

                for site in self.sites:
                    for site_pin in site.site_pins:
                        if site_pin.wire == wire:
                            sites.append((site.name, site_pin.name))

                for pip in self.pips:
                    pseudo_filter = (not pip.is_pseudo) or allow_pseudo
                    if (wire == pip.net_to
                            or wire == pip.net_from) and pseudo_filter:
                        pips.append(pip.name)

                assert wire not in self.wire_info
                self.wire_info[wire] = WireInfo(pips=pips, sites=sites)

        return self.wire_info[target_wire]

    def get_instance_sites(self, grid_info):
        """ get_sites returns abstract sites for all tiles of type.
            get_instance_sites converts site info from generic to specific
            based on a tile location.
            """

        site_names = set()

        for site in self.sites:
            site_name = '{}_X{}Y{}'.format(site.prefix, site.x, site.y)
            origin_x, origin_y = lib.find_origin_coordinate(
                site_name, grid_info.sites.keys())

            x = site.x + origin_x
            y = site.y + origin_y

            site_name = '{}_X{}Y{}'.format(site.prefix, x, y)

            if site_name not in grid_info.sites:
                type_count = 0
                for site_name_from_grid, site_type in grid_info.sites.items():
                    if site.type == site_type:
                        type_count += 1
                        site_name = site_name_from_grid

                assert type_count == 1, (site_name, type_count)

            site_names.add(site_name)
            assert site.type == grid_info.sites[site_name]

            yield Site(
                name=site_name,
                prefix=site.prefix,
                type=site.type,
                x=x,
                y=y,
                site_pins=site.site_pins,
            )

        assert site_names == set(grid_info.sites.keys())


def get_other_wire_from_pip(pip, wire):
    if wire == pip.net_to:
        return pip.net_from
    elif wire == pip.net_from:
        return pip.net_to
    else:
        assert False, (pip, wire)
