*** Settings ***
Documentation       Deferred Virtual Resource Type Tests (#331)
Library             Process
Library             OperatingSystem

*** Variables ***
${PYTHON}               python
${REMOTE_YAML}          ${CURDIR}/../examples/resource-types/remote.yaml
${SUBMODULE_YAML}       ${CURDIR}/../examples/resource-types/submodule.yaml
${SYMLINK_YAML}         ${CURDIR}/../examples/resource-types/symlink.yaml

*** Test Cases ***
Load Remote Virtual Type YAML And Validate
    [Documentation]    Load remote.yaml via schema loader and assert key fields
    ${script}=    Catenate    SEPARATOR=\n
    ...    from cleveragents.resource.schema import ResourceTypeConfigSchema
    ...    schema = ResourceTypeConfigSchema.from_yaml_file("${REMOTE_YAML}")
    ...    assert schema.name == "remote", f"name: {schema.name}"
    ...    assert schema.resource_kind == "virtual", f"kind: {schema.resource_kind}"
    ...    assert schema.sandbox_strategy == "none", f"strategy: {schema.sandbox_strategy}"
    ...    assert schema.built_in is True, f"built_in: {schema.built_in}"
    ...    assert schema.user_addable is False, f"user_addable: {schema.user_addable}"
    ...    assert len(schema.cli_args) == 0, f"cli_args: {len(schema.cli_args)}"
    ...    assert schema.equivalence is not None, "equivalence missing"
    ...    assert "url" in schema.equivalence["criteria"]
    ...    assert "git-remote" in schema.child_types
    ...    print("remote deferred virtual YAML validated successfully")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    remote load failed: ${result.stderr}
    Should Contain    ${result.stdout}    remote deferred virtual YAML validated successfully

Load Submodule Virtual Type YAML And Validate
    [Documentation]    Load submodule.yaml via schema loader and assert key fields
    ${script}=    Catenate    SEPARATOR=\n
    ...    from cleveragents.resource.schema import ResourceTypeConfigSchema
    ...    schema = ResourceTypeConfigSchema.from_yaml_file("${SUBMODULE_YAML}")
    ...    assert schema.name == "submodule", f"name: {schema.name}"
    ...    assert schema.resource_kind == "virtual", f"kind: {schema.resource_kind}"
    ...    assert schema.sandbox_strategy == "none", f"strategy: {schema.sandbox_strategy}"
    ...    assert schema.built_in is True, f"built_in: {schema.built_in}"
    ...    assert schema.user_addable is False, f"user_addable: {schema.user_addable}"
    ...    assert len(schema.cli_args) == 0, f"cli_args: {len(schema.cli_args)}"
    ...    assert schema.equivalence is not None, "equivalence missing"
    ...    assert "url" in schema.equivalence["criteria"]
    ...    assert "path" in schema.equivalence["criteria"]
    ...    assert "git-submodule" in schema.child_types
    ...    print("submodule deferred virtual YAML validated successfully")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    submodule load failed: ${result.stderr}
    Should Contain    ${result.stdout}    submodule deferred virtual YAML validated successfully

Load Symlink Virtual Type YAML And Validate
    [Documentation]    Load symlink.yaml via schema loader and assert key fields
    ${script}=    Catenate    SEPARATOR=\n
    ...    from cleveragents.resource.schema import ResourceTypeConfigSchema
    ...    schema = ResourceTypeConfigSchema.from_yaml_file("${SYMLINK_YAML}")
    ...    assert schema.name == "symlink", f"name: {schema.name}"
    ...    assert schema.resource_kind == "virtual", f"kind: {schema.resource_kind}"
    ...    assert schema.sandbox_strategy == "none", f"strategy: {schema.sandbox_strategy}"
    ...    assert schema.built_in is True, f"built_in: {schema.built_in}"
    ...    assert schema.user_addable is False, f"user_addable: {schema.user_addable}"
    ...    assert len(schema.cli_args) == 0, f"cli_args: {len(schema.cli_args)}"
    ...    assert schema.equivalence is not None, "equivalence missing"
    ...    assert "name" in schema.equivalence["criteria"]
    ...    assert "target_path" in schema.equivalence["criteria"]
    ...    assert "fs-symlink" in schema.child_types
    ...    assert "git-tree-entry" in schema.child_types
    ...    print("symlink deferred virtual YAML validated successfully")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    symlink load failed: ${result.stderr}
    Should Contain    ${result.stdout}    symlink deferred virtual YAML validated successfully

Load All Deferred Virtual YAMLs As Domain Models
    [Documentation]    Load all deferred virtual YAMLs as ResourceTypeSpec domain models
    ${script}=    Catenate    SEPARATOR=\n
    ...    import yaml
    ...    from cleveragents.domain.models.core.resource_type import ResourceTypeSpec
    ...    def check(path, expected_name, expected_criteria):
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}with open(path) as f:
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}config = yaml.safe_load(f)
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}spec = ResourceTypeSpec.from_config(config)
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.name == expected_name, f"name mismatch: {spec.name}"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert str(spec.resource_kind) == "virtual", f"kind: {spec.resource_kind}"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.equivalence is not None, "equivalence missing"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.equivalence["criteria"] == expected_criteria
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}cli_dict = spec.as_cli_dict()
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert "equivalence" in cli_dict, "missing equivalence in cli_dict"
    ...    check("${REMOTE_YAML}", "remote", ["url"])
    ...    check("${SUBMODULE_YAML}", "submodule", ["url", "path"])
    ...    check("${SYMLINK_YAML}", "symlink", ["name", "target_path"])
    ...    print("All deferred virtual domain models validated successfully")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    Domain model load failed: ${result.stderr}
    Should Contain    ${result.stdout}    All deferred virtual domain models validated successfully

Virtual Types Survive DB Bootstrap Roundtrip
    [Documentation]    Bootstrap in-memory DB and verify virtual types are retrievable
    ${script}=    Catenate    SEPARATOR=\n
    ...    from sqlalchemy import create_engine
    ...    from sqlalchemy.orm import sessionmaker
    ...    from cleveragents.infrastructure.database.models import Base
    ...    from cleveragents.application.services.resource_registry_service import ResourceRegistryService
    ...    engine = create_engine("sqlite:///:memory:", echo=False)
    ...    Base.metadata.create_all(engine)
    ...    factory = sessionmaker(bind=engine, expire_on_commit=False)
    ...    svc = ResourceRegistryService(session_factory=factory)
    ...    for name, expected_criteria in [("remote", ["url"]), ("submodule", ["url", "path"]), ("symlink", ["name", "target_path"])]:
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}spec = svc.show_type(name)
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec is not None, f"{name} not found after bootstrap"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert str(spec.resource_kind.value) == "virtual", f"{name} kind: {spec.resource_kind}"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.user_addable is False, f"{name} user_addable: {spec.user_addable}"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.equivalence is not None, f"{name} missing equivalence"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert spec.equivalence["criteria"] == expected_criteria, f"{name} criteria: {spec.equivalence}"
    ...    names = [t.name for t in svc.list_types()]
    ...    for vt in ["remote", "submodule", "symlink"]:
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert vt in names, f"{vt} not in list_types: {names}"
    ...    print("All virtual types survived DB bootstrap roundtrip")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    DB roundtrip failed: ${result.stderr}
    Should Contain    ${result.stdout}    All virtual types survived DB bootstrap roundtrip

Virtual Type Without Equivalence Fails Validation
    [Documentation]    Verify that creating a virtual type without equivalence raises an error
    ${script}=    Catenate    SEPARATOR=\n
    ...    from cleveragents.domain.models.core.resource_type import ResourceTypeSpec
    ...    try:
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}ResourceTypeSpec.from_config({"name": "bad-virtual", "resource_kind": "virtual", "sandbox_strategy": "none", "built_in": True})
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}print("ERROR: no exception raised")
    ...    except (ValueError, Exception) as e:
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}assert "equivalence" in str(e).lower(), f"Unexpected error: {e}"
    ...    ${SPACE}${SPACE}${SPACE}${SPACE}print("Correctly rejected virtual type without equivalence")
    ${result}=    Run Process    ${PYTHON}    -c    ${script}
    Should Be Equal As Integers    ${result.rc}    0    Validation test failed: ${result.stderr}
    Should Contain    ${result.stdout}    Correctly rejected virtual type without equivalence
