"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

import enum
import sys
from typing import Any

from pydantic_core import core_schema


class OpenEnumMeta(enum.EnumMeta):
    # The __call__ method `boundary` kwarg was added in 3.11 and must be present
    # for pyright. Refer also: https://github.com/pylint-dev/pylint/issues/9622
    # pylint: disable=unexpected-keyword-arg
    # The __call__ method `values` varg must be named for pyright.
    # pylint: disable=keyword-arg-before-vararg

    if sys.version_info >= (3, 11):
        def __call__(
            cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None
        ):
            # The `type` kwarg also happens to be a built-in that pylint flags as
            # redeclared. Safe to ignore this lint rule with this scope.
            # pylint: disable=redefined-builtin

            if names is not None:
                return super().__call__(
                    value,
                    names=names,
                    *values,
                    module=module,
                    qualname=qualname,
                    type=type,
                    start=start,
                    boundary=boundary,
                )

            try:
                return super().__call__(
                    value,
                    names=names,  # pyright: ignore[reportArgumentType]
                    *values,
                    module=module,
                    qualname=qualname,
                    type=type,
                    start=start,
                    boundary=boundary,
                )
            except ValueError:
                return value
    else:
        def __call__(
            cls, value, names=None, *, module=None, qualname=None, type=None, start=1
        ):
            # The `type` kwarg also happens to be a built-in that pylint flags as
            # redeclared. Safe to ignore this lint rule with this scope.
            # pylint: disable=redefined-builtin

            if names is not None:
                return super().__call__(
                    value,
                    names=names,
                    module=module,
                    qualname=qualname,
                    type=type,
                    start=start,
                )

            try:
                return super().__call__(
                    value,
                    names=names,  # pyright: ignore[reportArgumentType]
                    module=module,
                    qualname=qualname,
                    type=type,
                    start=start,
                )
            except ValueError:
                return value

    def __new__(mcs, name, bases, namespace, **kwargs):
        cls = super().__new__(mcs, name, bases, namespace, **kwargs)

        # Add __get_pydantic_core_schema__ to make open enums work correctly
        # in union discrimination. In strict mode (used by Pydantic for unions),
        # only known enum values match. In lax mode, unknown values are accepted.
        def __get_pydantic_core_schema__(
            cls_inner: Any, _source_type: Any, _handler: Any
        ) -> core_schema.CoreSchema:
            # Create a validator that only accepts known enum values (for strict mode)
            def validate_strict(v: Any) -> Any:
                if isinstance(v, cls_inner):
                    return v
                # Use the parent EnumMeta's __call__ which raises ValueError for unknown values
                return enum.EnumMeta.__call__(cls_inner, v)

            # Create a lax validator that accepts unknown values
            def validate_lax(v: Any) -> Any:
                if isinstance(v, cls_inner):
                    return v
                try:
                    return enum.EnumMeta.__call__(cls_inner, v)
                except ValueError:
                    # Return the raw value for unknown enum values
                    return v

            # Determine the base type schema (str or int)
            is_int_enum = False
            for base in cls_inner.__mro__:
                if base is int:
                    is_int_enum = True
                    break
                if base is str:
                    break

            base_schema = (
                core_schema.int_schema()
                if is_int_enum
                else core_schema.str_schema()
            )

            # Use lax_or_strict_schema:
            # - strict mode: only known enum values match (raises ValueError for unknown)
            # - lax mode: accept any value, return enum member or raw value
            return core_schema.lax_or_strict_schema(
                lax_schema=core_schema.chain_schema(
                    [base_schema, core_schema.no_info_plain_validator_function(validate_lax)]
                ),
                strict_schema=core_schema.chain_schema(
                    [base_schema, core_schema.no_info_plain_validator_function(validate_strict)]
                ),
            )

        setattr(cls, "__get_pydantic_core_schema__", classmethod(__get_pydantic_core_schema__))
        return cls
