from typing import Any
from dataclasses import dataclass, field
from enum import Enum


class NoDataclass: ...


class MyEnum(Enum):
    one = 1
    two = 2


@dataclass
class SubValue:
    default_int: int = 2
    default_float: float = field(default=1.2)
    default_sub: "Value" = field(default_factory=lambda: Value(1, 3.0, "str"))


@dataclass
class Value:
    a_int: int
    a_float: float
    a_string: str
    a_enum: MyEnum = MyEnum.one
    a_tuple: tuple[int, float] = field(default_factory=tuple[0, 2.0])
    a_list: list[SubValue] = field(default_factory=list)
    a_dict: dict[str, int] = field(default_factory=dict)
    a_subvalue: SubValue | None = None


@dataclass
class Case:
    name: str
    value: Any
    jdict: dict[str, Any]


CASES = [
    Case(
        "basic",
        Value(1, 2.0, "string"),
        {"a_int": 1, "a_float": 2.0, "a_string": "string"},
    ),
    Case(
        "with dataclass as field",
        Value(1, 2.0, "string", a_subvalue=SubValue(3)),
        {
            "a_int": 1,
            "a_float": 2.0,
            "a_string": "string",
            "a_subvalue": {"default_int": 3},
        },
    ),
    Case(
        "dataclass with dataclass field with all values",
        Value(1, 2.0, "string", a_subvalue=SubValue(1, 2.0, Value(3, 4.0, "sub"))),
        {
            "a_int": 1,
            "a_float": 2.0,
            "a_string": "string",
            "a_subvalue": {
                "default_int": 1,
                "default_float": 2.0,
                "default_sub": {"a_int": 3, "a_float": 4.0, "a_string": "sub"},
            },
        },
    ),
    Case(
        "dataclass with list, tuple and dict",
        Value(1, 2.0, "string", MyEnum.two, (1, 2.0), [SubValue()], {"a": 1}),
        {
            "a_int": 1,
            "a_float": 2.0,
            "a_string": "string",
            "a_enum": "two",
            "a_tuple": (1, 2.0),
            "a_list": [{}],
            "a_dict": {"a": 1},
        },
    ),
]
