"""Tests for restate_saga.virtual_objects."""

import restate

from restate_saga.virtual_objects import SagaVirtualObject, create_saga_virtual_object
from restate_saga.types import SagaWorkflowOptions, WorkflowRetryPolicy


# ---------------------------------------------------------------------------
# create_saga_virtual_object
# ---------------------------------------------------------------------------


def test_create_basic():
    obj = create_saga_virtual_object("TestObj")
    assert isinstance(obj, SagaVirtualObject)
    assert isinstance(obj, restate.VirtualObject)
    assert obj.name == "TestObj"


def test_create_with_options():
    opts = SagaWorkflowOptions(
        retry_policy=WorkflowRetryPolicy(max_attempts=5),
    )
    obj = create_saga_virtual_object("TestObj", options=opts)
    assert obj.name == "TestObj"


# ---------------------------------------------------------------------------
# Handler registration
# ---------------------------------------------------------------------------


def test_exclusive_handler_registered():
    obj = create_saga_virtual_object("ExcObj")

    @obj.handler()
    async def my_handler(saga, ctx, input_val):
        return {"ok": True}

    handler_names = list(obj.handlers)
    assert "my_handler" in handler_names


def test_shared_handler_registered():
    obj = create_saga_virtual_object("SharedObj")

    @obj.handler(kind="shared")
    async def get_status(ctx):
        return "ok"

    handler_names = list(obj.handlers)
    assert "get_status" in handler_names


def test_named_handler():
    obj = create_saga_virtual_object("NamedObj")

    @obj.handler(name="customName")
    async def my_handler(saga, ctx, input_val):
        return input_val

    handler_names = list(obj.handlers)
    assert "customName" in handler_names


def test_multiple_handlers():
    obj = create_saga_virtual_object("MultiObj")

    @obj.handler()
    async def exclusive_one(saga, ctx, input_val):
        return input_val

    @obj.handler(kind="shared")
    async def shared_one(ctx):
        return "shared"

    handler_names = list(obj.handlers)
    assert "exclusive_one" in handler_names
    assert "shared_one" in handler_names


# ---------------------------------------------------------------------------
# isinstance checks (important for restate.app())
# ---------------------------------------------------------------------------


def test_isinstance_virtual_object():
    obj = create_saga_virtual_object("CheckObj")
    assert isinstance(obj, restate.VirtualObject)


# ---------------------------------------------------------------------------
# Subclass behavior
# ---------------------------------------------------------------------------


def test_saga_virtual_object_is_subclass():
    assert issubclass(SagaVirtualObject, restate.VirtualObject)
