#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 The SkyWater PDK Authors.
#
# Use of this source code is governed by the Apache 2.0
# license that can be found in the LICENSE file or at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0

import re
import os

from enum import Flag
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import Tuple, Optional

from . import base
from .utils import OrderedFlag
from .utils import comparable_to_none


CornerTypeMappings = {}
# "wo" is "worst-case one" and corresponds to "fs"
CornerTypeMappings["wo"] = "fs"
# "wz" is "worst-case zero" and corresponds to "sf"
CornerTypeMappings["wz"] = "sf"
# "wp" is "worst-case power" and corresponds to "ff"
CornerTypeMappings["wp"] = "ff"
# "ws" is "worst-case speed" and corresponds to "ss"
CornerTypeMappings["ws"] = "ss"


class CornerType(OrderedFlag):
    """
    >>> CornerType.parse('t')
    CornerType.t
    >>> CornerType.parse('tt')
    [CornerType.t, CornerType.t]
    >>> CornerType.parse('wp')
    [CornerType.f, CornerType.f]
    """
    t = 'Typical'  # all  nominal (typical) values
    f = 'Fast'     # fast, that is, values that make transistors run faster
    s = 'Slow'     # slow

    @classmethod
    def parse(cls, s):
        if s in CornerTypeMappings:
            return cls.parse(CornerTypeMappings[s])
        if len(s) > 1:
            try:
                o = []
                for c in s:
                    o.append(cls.parse(c))
                return o
            except TypeError:
                raise TypeError("Unknown corner type: {}".format(s))
        if not hasattr(cls, s):
            raise TypeError("Unknown corner type: {}".format(s))
        return getattr(cls, s)

    def __repr__(self):
        return 'CornerType.'+self.name

    def __str__(self):
        return self.value


class CornerFlag(OrderedFlag):
    nointpr = 'No internal power'
    lv = 'Low voltage'
    ccsnoise = 'Composite Current Source Noise'
    pwr = 'Power'

    @classmethod
    def parse(cls, s):
        if hasattr(cls, s):
            return getattr(cls, s)
        else:
            raise TypeError("Unknown CornerFlags: {}".format(s))

    def __repr__(self):
        return 'CornerFlag.'+self.name

    def __str__(self):
        return self.value


@comparable_to_none
class OptionalTuple(tuple):
    pass


@comparable_to_none
@dataclass_json
@dataclass(frozen=True, order=True)
class Corner:
    corner: Tuple[CornerType, CornerType]
    volts: Tuple[float, ...]
    temps: Tuple[int, ...]
    flags: Optional[Tuple[CornerFlag, ...]] = None

    def __post_init__(self):
        if self.flags:
            object.__setattr__(self, 'flags', OptionalTuple(self.flags))


VOLTS_REGEX = re.compile('([0-9]p[0-9]+)V')
TEMP_REGEX = re.compile('(n?)([0-9][0-9]+)C')
def parse_filename(pathname):
    """Extract corner information from a filename.

    >>> parse_filename('tt_1p80V_3p30V_3p30V_25C')
    Corner(corner=(CornerType.t, CornerType.t), volts=(1.8, 3.3, 3.3), temps=(25,), flags=None)

    >>> parse_filename('sky130_fd_io__top_ground_padonlyv2__tt_1p80V_3p30V_3p30V_25C.wrap.lib')
    Corner(corner=(CornerType.t, CornerType.t), volts=(1.8, 3.3, 3.3), temps=(25,), flags=None)

    >>> parse_filename('sky130_fd_sc_ms__tt_1p80V_100C.wrap.json')
    Corner(corner=(CornerType.t, CornerType.t), volts=(1.8,), temps=(100,), flags=None)

    >>> parse_filename('sky130_fd_sc_ms__tt_1p80V_100C.wrap.lib')
    Corner(corner=(CornerType.t, CornerType.t), volts=(1.8,), temps=(100,), flags=None)

    >>> parse_filename('sky130_fd_sc_ms__tt_1p80V_25C_ccsnoise.wrap.json')
    Corner(corner=(CornerType.t, CornerType.t), volts=(1.8,), temps=(25,), flags=(CornerFlag.ccsnoise,))

    >>> parse_filename('sky130_fd_sc_ms__wp_1p65V_n40C.wrap.json')
    Corner(corner=(CornerType.f, CornerType.f), volts=(1.65,), temps=(-40,), flags=None)

    >>> parse_filename('sky130_fd_sc_ms__wp_1p95V_85C_pwr.wrap.lib')
    Corner(corner=(CornerType.f, CornerType.f), volts=(1.95,), temps=(85,), flags=(CornerFlag.pwr,))

    >>> parse_filename('sky130_fd_sc_ms__wp_1p95V_n40C_ccsnoise.wrap.json')
    Corner(corner=(CornerType.f, CornerType.f), volts=(1.95,), temps=(-40,), flags=(CornerFlag.ccsnoise,))

    >>> parse_filename('sky130_fd_sc_ms__wp_1p95V_n40C_pwr.wrap.lib')
    Corner(corner=(CornerType.f, CornerType.f), volts=(1.95,), temps=(-40,), flags=(CornerFlag.pwr,))

    >>> parse_filename('sky130_fd_sc_hd__a2111o_4__ss_1p76V_n40C.cell.json')
    Corner(corner=(CornerType.s, CornerType.s), volts=(1.76,), temps=(-40,), flags=None)

    """
    if base.SEPERATOR in pathname:
        cell, extra, extension = base.parse_filename(pathname)
    else:
        cell = None
        extra = pathname
        extension = ''

    if extension not in ('', 'lib', 'cell.lib', 'cell.json', 'wrap.lib', 'wrap.json'):
        raise ValueError('Not possible to extract corners from: {!r}'.format(extension))

    if not extra:
        extra = cell.name
        cell = None

    kw = {}
    kw['flags'] = []
    kw['volts'] = []
    kw['temps'] = []

    bits = extra.split("_")
    while len(bits) > 0:
        b = bits.pop(0)

        if VOLTS_REGEX.match(b):
            assert b.endswith('V'), b
            kw['volts'].append(float(b[:-1].replace('p', '.')))
        elif TEMP_REGEX.match(b):
            assert b.endswith('C'), b
            kw['temps'].append(int(b[:-1].replace('n', '-')))
        else:
            if 'corner' not in kw:
                kw['corner'] = CornerType.parse(b)
            else:
                kw['flags'].append(CornerFlag.parse(b))

    for k, v in kw.items():
        kw[k] = tuple(v)

    if not kw['flags']:
        del kw['flags']

    return Corner(**kw)



# 1p60V 5p50V n40C




if __name__ == "__main__":
    import doctest
    doctest.testmod()
