#!/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(lp_variant=0), DriveStrengthMinimum(), DriveStrengthNumeric(units=2)]
    >>> l.sort()
    >>> l
    [DriveStrengthNumeric(units=1), DriveStrengthNumeric(units=2), DriveStrengthLowPower(lp_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("_-1")
    Traceback (most recent call last):
        ...
    InvalidSuffixError: Invalid suffix: _-1
    >>> 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(lp_variant=0)
    >>> lp2
    DriveStrengthLowPower(lp_variant=1)
    >>> lp3
    DriveStrengthLowPower(lp_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'
    """
    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 "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 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'

    >>> m1 = DriveStrengthMinimum()
    >>> m2 = DriveStrengthMinimum()
    >>> 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 "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()

    def __hash__(self):
        return id(self)

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


DriveStrengthMinimum._object = DriveStrengthMinimum()


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