from __future__ import annotations

import sys
from typing import Optional

import pytest
from typing_extensions import Annotated

import cappa
from tests.utils import Backend, backends, parse

if sys.version_info >= (3, 9):
    try:
        import msgspec

        HAVE_MSGSPEC = True

        class PydanticCommand(msgspec.Struct):
            name: str
            foo: Annotated[int, cappa.Arg(short=True)]

        class OptSub(msgspec.Struct):
            name: Optional[str] = None

        class OptionalSubcommand(msgspec.Struct):
            sub: cappa.Subcommands[Optional[OptSub]] = None

    except ImportError:
        HAVE_MSGSPEC = False  # pyright: ignore[reportConstantRedefinition]

    @pytest.mark.skipif(not HAVE_MSGSPEC, reason="msgspec not installed")
    @backends
    def test_base_model(backend: Backend):
        result = parse(PydanticCommand, "meow", "-f", "4", backend=backend)
        assert result == PydanticCommand(name="meow", foo=4)

    @pytest.mark.skipif(not HAVE_MSGSPEC, reason="msgspec not installed")
    @backends
    def test_optional_subcommand(backend: Backend):
        result = parse(OptionalSubcommand, backend=backend)
        assert result == OptionalSubcommand(sub=None)

        result = parse(OptionalSubcommand, "opt-sub", backend=backend)
        assert result == OptionalSubcommand(sub=OptSub(name=None))

        result = parse(OptionalSubcommand, "opt-sub", "foo", backend=backend)
        assert result == OptionalSubcommand(sub=OptSub(name="foo"))
