#!/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 abc
import os
import operator

from dataclasses import dataclass
from dataclasses_json import dataclass_json


def parse_size(s):
    """

    >>> parse_size('_1')
    TransistorSizeNumeric(units=1)

    >>> parse_size('sky130_fd_sc_ms__sdfrtp_1.v')
    TransistorSizeNumeric(units=1)

    >>> parse_size('libraries/sky130_fd_sc_ms/v0.0.1/cells/sdfrtp/sky130_fd_sc_ms__sdfrtp_1.v')
    TransistorSizeNumeric(units=1)

    >>> parse_size('libraries/sky130_fd_sc_ms/v0.0.1/cells/sdfrtp/sky130_fd_sc_ms__sdfrtp_1.bb.blackbox.v')
    TransistorSizeNumeric(units=1)

    >>> parse_size('libraries/sky130_fd_sc_ms/v0.0.1/cells/sdfrtp/sky130_fd_sc_ms__sdfrtp.v')
    >>> parse_size('sky130_fd_sc_ms__sdfrtp.v')
    >>> parse_size('_blah')
    """
    dirname, s = os.path.split(s)
    if '.' in s:
        s = s.split('.', 1)[0]
    if s.count('_') > 1:
        s = '_' + (s.rsplit('_', 1)[-1])
    if not s or s == '_':
        return None
    try:
        return TransistorSize.from_suffix(s)
    except InvalidSuffixError as e:
        return None


class InvalidSuffixError(ValueError):
    def __init__(self, s):
        ValueError.__init__(self, "Invalid suffix: {}".format(s.strip()))


class TransistorSize(abc.ABC):
    """Drive strength variants of a given cell.

    >>> d1 = TransistorSize.from_suffix("_1")
    >>> d2 = TransistorSize.from_suffix("_lp")
    >>> d3 = TransistorSize.from_suffix("_m")
    >>> d4 = TransistorSize.from_suffix("_2")
    >>> TransistorSize.from_suffix("_abc")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _abc
    >>> l = [d1, d2, d3, d4]
    >>> l
    [TransistorSizeNumeric(units=1), TransistorSizeLowPower(lp_variant=0), TransistorSizeMinimum(), TransistorSizeNumeric(units=2)]
    >>> l.sort()
    >>> l
    [TransistorSizeNumeric(units=1), TransistorSizeNumeric(units=2), TransistorSizeLowPower(lp_variant=0), TransistorSizeMinimum()]
    """

    @abc.abstractmethod
    def describe(self):
        raise NotImplementedError

    @property
    @abc.abstractmethod
    def suffix(self):
        raise NotImplementedError

    @classmethod
    def from_suffix(cls, s):
        errors = []
        for subcls in cls.__subclasses__():
            try:
                return subcls.from_suffix(s)
            except (ValueError, AssertionError) as e:
                errors.append((subcls.__name__, e))
        assert errors, ("Unknown error!?", s)
        msg = [s, '']
        for cls_name, e in errors:
            if isinstance(e, ValueError):
                continue
            msg.append("{} failed with: {}".format(cls_name, e))
        raise InvalidSuffixError("\n".join(msg))

    def __str__(self):
        return "with size {}".format(self.describe())

    def _cmp(self, op, o):
        if not isinstance(o, TransistorSize):
            return False
        return op(self.suffix, o.suffix)

    # Comparison operators
    def __lt__(self, o):
        return self._cmp(operator.lt, o)

    def __le__(self, o):
        return self._cmp(operator.le, o)

    def __eq__(self, o):
        return self._cmp(operator.eq, o)

    def __ne__(self, o):
        return self._cmp(operator.ne, o)

    def __ge__(self, o):
        return self._cmp(operator.ge, o)

    def __gt__(self, o):
        return self._cmp(operator.gt, o)


@dataclass_json
@dataclass(frozen=True)
class TransistorSizeNumeric(TransistorSize):
    """
    >>> s1 = TransistorSizeNumeric.from_suffix("_1")
    >>> s2 = TransistorSizeNumeric.from_suffix("_2")
    >>> s3 = TransistorSizeNumeric.from_suffix("_3")
    >>> TransistorSizeNumeric.from_suffix("_-1")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _-1
    >>> s1
    TransistorSizeNumeric(units=1)
    >>> s2
    TransistorSizeNumeric(units=2)
    >>> s3
    TransistorSizeNumeric(units=3)
    >>> str(s1)
    'with size of 1 units'
    >>> str(s2)
    'with size of 2 units'
    >>> str(s3)
    'with size of 3 units (invalid?)'
    >>> s1.describe()
    'of 1 units'
    >>> s2.describe()
    'of 2 units'
    >>> s3.describe()
    'of 3 units (invalid?)'
    >>> s1.suffix
    '_1'
    >>> s2.suffix
    '_2'
    >>> s3.suffix
    '_3'
    """
    units: int

    VALID_UNIT_VALUES = (0, 1, 2, 4, 8, 6, 12, 14, 16, 20, 32)

    def describe(self):
        suffix = ""
        if self.units not in self.VALID_UNIT_VALUES:
            suffix = " (invalid?)"

        return "of {} units{}".format(self.units, suffix)

    @property
    def suffix(self):
        return "_{}".format(self.units)

    @classmethod
    def from_suffix(cls, s):
        if not s.startswith("_"):
            raise InvalidSuffixError(s)
        i = int(s[1:])
        if i < 0:
            raise InvalidSuffixError(s)
        return cls(i)


@dataclass_json
@dataclass(frozen=True)
class TransistorSizeLowPower(TransistorSize):
    """
    >>> lp = TransistorSizeLowPower.from_suffix("_lp")
    >>> lp2 = TransistorSizeLowPower.from_suffix("_lp2")
    >>> lp3 = TransistorSizeLowPower.from_suffix("_lp3")
    >>> TransistorSizeLowPower.from_suffix("_ld")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _ld
    >>> lp
    TransistorSizeLowPower(lp_variant=0)
    >>> lp2
    TransistorSizeLowPower(lp_variant=1)
    >>> lp3
    TransistorSizeLowPower(lp_variant=2)
    >>> str(lp)
    'with size for low power'
    >>> str(lp2)
    'with size for low power (alternative)'
    >>> str(lp3)
    'with size for low power (extra alternative 0)'
    >>> lp.describe()
    'for low power'
    >>> lp2.describe()
    'for low power (alternative)'
    >>> lp3.describe()
    'for low power (extra alternative 0)'
    >>> lp.suffix
    '_lp'
    >>> lp2.suffix
    '_lp2'
    >>> lp3.suffix
    '_lp3'
    """
    lp_variant: int = 0

    def describe(self):
        if self.lp_variant == 0:
            suffix = ""
        elif self.lp_variant == 1:
            suffix = " (alternative)"
        else:
            assert self.lp_variant >= 2, self.lp_variant
            suffix = " (extra alternative {})".format(self.lp_variant-2)
        return "for low power"+suffix

    @property
    def suffix(self):
        if self.lp_variant == 0:
            return "_lp"
        else:
            assert self.lp_variant > 0, self.lp_variant
            return "_lp{}".format(self.lp_variant+1)

    @classmethod
    def from_suffix(cls, s):
        if not s.startswith("_lp"):
            raise InvalidSuffixError(s)
        if s == "_lp":
            return cls()
        elif s == "_lp2":
            return cls(1)
        else:
            try:
                i = int(s[3:])
            except ValueError as e:
                raise InvalidSuffixError(s)
            assert i > 2, (s, i)
            return cls(i-1)


class TransistorSizeMinimum(TransistorSize):
    """
    >>> m = TransistorSizeMinimum.from_suffix("_m")
    >>> TransistorSizeMinimum.from_suffix("_m2")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _m2
    >>> m
    TransistorSizeMinimum()
    >>> str(m)
    'with size minimum'
    >>> m.describe()
    'minimum'
    >>> m.suffix
    '_m'

    >>> m1 = TransistorSizeMinimum()
    >>> m2 = TransistorSizeMinimum()
    >>> assert m1 is m2
    """
    _object = None
    def __new__(cls):
        if cls._object is None:
            cls._object = object.__new__(cls)
        return cls._object

    def __repr__(self):
        return "TransistorSizeMinimum()"

    def describe(self):
        return "minimum"

    @property
    def suffix(self):
        return "_m"

    @classmethod
    def from_suffix(cls, s):
        if s != "_m":
            raise InvalidSuffixError(s)
        return cls()

    def __hash__(self):
        return id(self)

    def to_dict(self):
        return {'minimum': None}


TransistorSizeMinimum._object = TransistorSizeMinimum()


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