# SPDX-FileCopyrightText: 2025-2026 Global Computing Lab
#
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from __future__ import annotations

try:
    from enum import StrEnum
except ImportError:
    from enum import Enum
    from typing import Any

    class StrEnum(str, Enum):
        """Simple backport of enum.StrEnum for Python < 3.11."""

        # The implementation of this function borrows heavily from the implementation
        # of `enum.StrEnum.__new__` in Python 3.11+. The source code for that method
        # can be found here:
        # https://github.com/python/cpython/blob/a17301ab3d04a3ebf79ffac754570294d9025023/Lib/enum.py#L1375
        def __new__(cls, *values: Any) -> StrEnum:
            # Validate number of arguments
            if len(values) > 3:  # noqa: PLR2004
                raise TypeError("Too many arguments provided for StrEnum variant: {!r}".format(values))
            # Validate the first argument, if provided
            if len(values) == 1:
                if not isinstance(values[0], str):
                    raise TypeError(
                        "The first argument for a StrEnum variant must be a string. Got {!r}".format(values[0])
                    )
            # Validate the second argument, if provided
            if len(values) >= 2:  # noqa: PLR2004
                if not isinstance(values[1], str):
                    raise TypeError(
                        "The second argument for a StrEnum variant must be a string representing the encoding. Got {!r}".format(  # noqa: E501
                            values[1]
                        )
                    )
            # Validate the third argument, if provided
            if len(values) == 3:  # noqa: PLR2004
                if not isinstance(values[2], str):
                    raise TypeError(
                        "The third argument for a StrEnum variant must be a string representing how to handle errors. Got {!r}".format(  # noqa: E501
                            values[2]
                        )
                    )
            # Create the value with the `str` constructor
            value = str(*values)
            # Create the enum member in a way that allows the member to behave
            # like a string
            member = str.__new__(cls, value)
            # Set the `__value__` field so that the enum machinery actually knows
            # how to handle the member
            member._value_ = value
            return member

        def __str__(self) -> str:
            return self.value

        @staticmethod
        def _generate_next_value_(name: str, start: int, count: int, last_values: list[Any]) -> str:
            return name.lower()
