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

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