#!/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


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


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

    >>> d1 = DriveStrength.from_suffix("_1")
    >>> d2 = DriveStrength.from_suffix("_lp")
    >>> d3 = DriveStrength.from_suffix("_m")
    >>> d4 = DriveStrength.from_suffix("_2")
    >>> DriveStrength.from_suffix("_abc")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _abc
    >>> l = [d1, d2, d3, d4]
    >>> l
    [DriveStrengthNumeric(units=1), DriveStrengthLowPower(variant=0), DriveStrengthMinimum(), DriveStrengthNumeric(units=2)]
    >>> l.sort()
    >>> l
    [DriveStrengthNumeric(units=1), DriveStrengthNumeric(units=2), DriveStrengthLowPower(variant=0), DriveStrengthMinimum()]
    """

    @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 "drive strength {}".format(self.describe())

    def _cmp(self, op, o):
        if not isinstance(o, DriveStrength):
            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 DriveStrengthNumeric(DriveStrength):
    """
    >>> s1 = DriveStrengthNumeric.from_suffix("_1")
    >>> s2 = DriveStrengthNumeric.from_suffix("_2")
    >>> s3 = DriveStrengthNumeric.from_suffix("_3")
    >>> DriveStrengthNumeric.from_suffix("_0")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _0
    >>> s1
    DriveStrengthNumeric(units=1)
    >>> s2
    DriveStrengthNumeric(units=2)
    >>> s3
    DriveStrengthNumeric(units=3)
    >>> str(s1)
    'drive strength 1 units'
    >>> str(s2)
    'drive strength 2 units'
    >>> str(s3)
    'drive strength 3 units (invalid?)'
    >>> s1.describe()
    '1 units'
    >>> s2.describe()
    '2 units'
    >>> s3.describe()
    '3 units (invalid?)'
    >>> s1.suffix
    '_1'
    >>> s2.suffix
    '_2'
    >>> s3.suffix
    '_3'
    """
    units: int

    def describe(self):
        suffix = ""
        if self.units not in (1, 2, 4):
            suffix = " (invalid?)"

        return "{} 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 DriveStrengthLowPower(DriveStrength):
    """
    >>> lp = DriveStrengthLowPower.from_suffix("_lp")
    >>> lp2 = DriveStrengthLowPower.from_suffix("_lp2")
    >>> lp3 = DriveStrengthLowPower.from_suffix("_lp3")
    >>> DriveStrengthLowPower.from_suffix("_ld")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _ld
    >>> lp
    DriveStrengthLowPower(variant=0)
    >>> lp2
    DriveStrengthLowPower(variant=1)
    >>> lp3
    DriveStrengthLowPower(variant=2)
    >>> str(lp)
    'drive strength Low Power'
    >>> str(lp2)
    'drive strength Low Power (alternative)'
    >>> str(lp3)
    'drive strength Low Power (extra alternative 0)'
    >>> lp.describe()
    'Low Power'
    >>> lp2.describe()
    'Low Power (alternative)'
    >>> lp3.describe()
    'Low Power (extra alternative 0)'
    >>> lp.suffix
    '_lp'
    >>> lp2.suffix
    '_lp2'
    >>> lp3.suffix
    '_lp3'
    """
    variant: int = 0

    def describe(self):
        if self.variant == 0:
            suffix = ""
        elif self.variant == 1:
            suffix = " (alternative)"
        else:
            assert self.variant >= 2, self.variant
            suffix = " (extra alternative {})".format(self.variant-2)
        return "Low Power"+suffix

    @property
    def suffix(self):
        if self.variant == 0:
            return "_lp"
        else:
            assert self.variant > 0, self.variant
            return "_lp{}".format(self.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 DriveStrengthMinimum(DriveStrength):
    """
    >>> m = DriveStrengthMinimum.from_suffix("_m")
    >>> DriveStrengthMinimum.from_suffix("_m2")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _m2
    >>> m
    DriveStrengthMinimum()
    >>> str(m)
    'drive strength minimum'
    >>> m.describe()
    'minimum'
    >>> m.suffix
    '_m'
    """

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

    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()


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