#!/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_drive(s):
    return DriveStrength.from_suffix(s)


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

    VALID_UNIT_VALUES = (0, 1, 2, 4)

    def describe(self):
        suffix = ""
        if self.units not in self.VALID_UNIT_VALUES:
            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()
