#!/usr/bin/env python3
"""Repro test for stale state detection in `anima ls` command.

This script verifies that:
1. Running agents with dead PIDs are auto-reaped
2. The failed state is surfaced in `anima ls` output
3. Behavior is clear/non-noisy for users
"""

import os
import sys
import tempfile
from pathlib import Path

# Add project root to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from anima.core.schemas import AgentState, AgentStateData
from anima.shell.state import (
    get_state_dir,
    write_state,
)


def get_dead_pid() -> int:
    """Get a PID that definitely doesn't exist."""
    # Try to find a dead PID
    for pid in range(30000, 40000):
        try:
            os.kill(pid, 0)
        except OSError as e:
            if e.errno == 3:  # ESRCH - no such process
                return pid
    # Fallback: use a very high PID
    return 999999


def create_stale_running_agent(instance_id: str, dead_pid: int) -> None:
    """Create a running agent state with a dead PID."""
    state_dir = get_state_dir()
    agent_dir = state_dir / "agents" / instance_id
    agent_dir.mkdir(parents=True, exist_ok=True)

    # Write state file with running state and dead PID
    from anima.core.schemas.enums import LifecycleType

    state_data = AgentStateData(
        instance_id=instance_id,
        persona_name="test-stale",
        trace_id=f"trace-{instance_id}",
        state=AgentState.running,
        pid=dead_pid,
        lifecycle=LifecycleType.ephemeral,
        created_at="2025-01-01T00:00:00Z",
        updated_at="2025-01-01T00:00:00Z",
    )

    result = write_state(instance_id, state_data)
    from returns.result import Failure

    if isinstance(result, Failure):
        raise RuntimeError(f"Failed to create stale agent: {result.failure()}")


def test_stale_ls_detection():
    """Test that `anima ls` detects and reaps stale running agents."""
    print("\n" + "=" * 60)
    print("STALE DETECTION TEST: anima ls with dead-PID agent")
    print("=" * 60)

    # Create test agent directory
    with tempfile.TemporaryDirectory() as tmpdir:
        test_state_dir = Path(tmpdir) / "state"
        os.environ["ANIMA_STATE"] = str(test_state_dir)

        # Re-import to pick up new state dir
        import importlib

        import anima.shell.state

        importlib.reload(anima.shell.state)

        from anima.shell.cli_commands.query import _check_and_reap_stale_agents

        # Create a running agent with dead PID
        dead_pid = get_dead_pid()
        agent_id = "test-stale-ls-agent"

        print(f"\nStep 1: Creating agent in running state with dead PID {dead_pid}")
        create_stale_running_agent(agent_id, dead_pid)

        # Read the initial state
        from anima.shell.state import read_state
        from returns.result import Success

        initial_result = read_state(agent_id)
        assert isinstance(initial_result, Success)
        initial_state = initial_result.unwrap()
        print(f"  Initial state: {initial_state.state.value}")
        print(f"  Initial PID: {initial_state.pid}")
        assert initial_state.state == AgentState.running

        # Create a list with the stale agent
        agents = [initial_state]

        print("\nStep 2: Running stale detection")
        updated_agents = _check_and_reap_stale_agents(agents)

        print("\nStep 3: Verifying auto-reap")
        assert len(updated_agents) == 1
        reaped_agent = updated_agents[0]

        print(f"  Reaped state: {reaped_agent.state.value}")
        print(f"  Reaped error: {reaped_agent.error}")

        # Verify the agent is now failed
        assert reaped_agent.state == AgentState.failed
        assert reaped_agent.error is not None
        assert "stale" in reaped_agent.error.lower()

        # Verify the on-disk state was updated
        final_result = read_state(agent_id)
        assert isinstance(final_result, Success)
        final_state = final_result.unwrap()
        assert final_state.state == AgentState.failed

        print("\n" + "=" * 60)
        print("✓ PASS: Stale agent was auto-reaped")
        print("  - Running agent with dead PID detected")
        print("  - Agent transitioned to failed state")
        print("  - Error message indicates stale state")
        print("  - User sees accurate failed state (not noisy running)")
        print("=" * 60)

        return 0


if __name__ == "__main__":
    try:
        sys.exit(test_stale_ls_detection())
    except Exception as e:
        print(f"\n✗ FAIL: {e}")
        import traceback

        traceback.print_exc()
        sys.exit(1)
