#!/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
from .utils import dataclass_json_passthru_sequence_config as dj_pass_cfg


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

    def to_json(self):
        return self.name


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

    def to_json(self):
        return self.name


@comparable_to_none
class OptionalTuple(tuple):
    pass


@comparable_to_none
@dataclass_json
@dataclass(frozen=True, order=True)
class Corner:
    corner: Tuple[CornerType, CornerType] = dj_pass_cfg()
    volts: Tuple[float, ...] = dj_pass_cfg()
    temps: Tuple[int, ...] = dj_pass_cfg()
    flags: Optional[Tuple[CornerFlag, ...]] = dj_pass_cfg(default=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()
