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


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