"""Tests for core types — protocols, result types, and config models."""

from __future__ import annotations

from agentsh_secure_sandbox.core.types import (
    ExecResult,
    WriteFileSuccess,
    WriteFileFailure,
    ReadFileSuccess,
    ReadFileFailure,
    ExecOpts,
    SandboxAdapter,
    SecureConfig,
    ThreatFeed,
)


def test_exec_result_frozen():
    r = ExecResult(stdout="hi", stderr="", exit_code=0)
    assert r.stdout == "hi"
    assert r.exit_code == 0
    try:
        r.stdout = "no"  # type: ignore[misc]
        assert False, "Should be frozen"
    except AttributeError:
        pass


def test_write_file_result_types():
    s = WriteFileSuccess(success=True, path="/a")
    assert s.success is True
    f = WriteFileFailure(success=False, path="/a", error="denied")
    assert f.success is False


def test_read_file_result_types():
    s = ReadFileSuccess(success=True, path="/a", content="data")
    assert s.content == "data"
    f = ReadFileFailure(success=False, path="/a", error="denied")
    assert f.error == "denied"


def test_exec_opts_defaults():
    opts = ExecOpts()
    assert opts.cwd is None
    assert opts.sudo is False
    assert opts.detached is False


def test_sandbox_adapter_is_protocol():
    # Runtime checkable
    class Dummy:
        async def exec(self, cmd, args=None, opts=None): ...
        async def write_file(self, path, content, *, sudo=False): ...
        async def read_file(self, path): ...
        async def stop(self): ...
        async def file_exists(self, path): ...

    assert isinstance(Dummy(), SandboxAdapter)


def test_secure_config_defaults():
    cfg = SecureConfig()
    assert cfg.workspace == "/workspace"
    assert cfg.install_strategy == "download"
    assert cfg.policy is None


def test_secure_config_rejects_extra_fields():
    import pytest
    from pydantic import ValidationError

    with pytest.raises(ValidationError):
        SecureConfig(bogus_field="nope")  # type: ignore[call-arg]


def test_threat_feed():
    tf = ThreatFeed(name="test", url="http://example.com", format="hostfile")
    assert tf.refresh_interval == "6h"


def test_security_mode_accepts_ptrace():
    cfg = SecureConfig(security_mode="ptrace")
    assert cfg.security_mode == "ptrace"


def test_server_config_ptrace():
    from agentsh_secure_sandbox.core.types import PtraceConfig, PtraceTraceConfig, PtracePerformanceConfig, ServerConfig
    sc = ServerConfig(ptrace=PtraceConfig(
        enabled=True, attach_mode="children",
        trace=PtraceTraceConfig(execve=True, file=False, network=True, signal=True),
        performance=PtracePerformanceConfig(seccomp_prefilter=False, max_tracees=500),
        on_attach_failure="fail_open",
    ))
    assert sc.ptrace.enabled is True
    assert sc.ptrace.trace.network is True


def test_secure_config_skip_shim():
    cfg = SecureConfig(skip_shim=True)
    assert cfg.skip_shim is True


def test_secure_config_server_config():
    from agentsh_secure_sandbox.core.types import ServerConfig
    cfg = SecureConfig(server_config=ServerConfig(allow_degraded=True))
    assert cfg.server_config.allow_degraded is True


def test_secure_config_package_checks():
    from agentsh_secure_sandbox.core.types import PackageChecksConfig
    cfg = SecureConfig(package_checks=PackageChecksConfig(scope="all_installs"))
    assert cfg.package_checks.scope == "all_installs"


def test_secure_config_package_checks_disabled():
    cfg = SecureConfig(package_checks=False)
    assert cfg.package_checks is False
