#!/usr/bin/env python3
"""Smoke Test 3: Exec Command

Tests that command execution works correctly and returns expected output.

Usage:
    ./test_exec.py <DEVICE_HASH>

Requirements:
    - Device agent must be running
    - Your identity must be authorized for 'exec' permission
    - 'echo' command must be in command allowlist
"""

import asyncio
import sys
from pathlib import Path

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

from styrene.services.rpc_client import RPCClient
from styrene.services.lxmf_service import get_lxmf_service
from styrene.services.reticulum import initialize_reticulum, get_operator_identity_object


async def test_exec(device_hash: str):
    """Test command execution.

    Args:
        device_hash: Target device identity hash
    """
    print("=" * 60)
    print("SMOKE TEST 3: Exec Command")
    print("=" * 60)
    print()

    # Initialize Reticulum
    print("Initializing Reticulum...")
    initialize_reticulum(headless=True)
    identity = get_operator_identity_object()
    print(f"Operator identity: {identity.hexhash}")
    print()

    # Initialize LXMF
    print("Initializing LXMF service...")
    lxmf = get_lxmf_service()
    lxmf.initialize(identity)
    print()

    # Create RPC client
    print("Creating RPC client...")
    client = RPCClient(lxmf)
    print()

    # Test cases
    test_cases = [
        {
            "name": "Simple echo",
            "command": "echo",
            "args": ["Hello", "World"],
            "expected_output": "Hello World",
            "expected_exit": 0,
        },
        {
            "name": "Echo with special characters",
            "command": "echo",
            "args": ["test@example.com", "path/to/file"],
            "expected_output": "test@example.com path/to/file",
            "expected_exit": 0,
        },
    ]

    passed = 0
    failed = 0

    for i, test in enumerate(test_cases, 1):
        print(f"Test {i}/{len(test_cases)}: {test['name']}")
        print(f"  Command: {test['command']} {' '.join(test['args'])}")

        try:
            result = await client.call_exec(
                device_hash,
                test["command"],
                test["args"],
                timeout=10.0
            )

            # Check exit code
            if result.exit_code != test["expected_exit"]:
                print(f"  ✗ FAIL: Exit code {result.exit_code} (expected {test['expected_exit']})")
                failed += 1
                continue

            # Check output
            output = result.stdout.strip()
            if test["expected_output"] not in output:
                print(f"  ✗ FAIL: Output mismatch")
                print(f"    Expected: {test['expected_output']}")
                print(f"    Got:      {output}")
                failed += 1
                continue

            print(f"  ✓ PASS")
            print(f"    Exit code: {result.exit_code}")
            print(f"    Output:    {output}")
            passed += 1

        except TimeoutError:
            print(f"  ✗ TIMEOUT: Device did not respond")
            failed += 1

        except Exception as e:
            print(f"  ✗ ERROR: {e}")
            failed += 1

        print()

    # Summary
    print("=" * 60)
    print("TEST SUMMARY")
    print("=" * 60)
    print(f"Passed: {passed}/{len(test_cases)}")
    print(f"Failed: {failed}/{len(test_cases)}")
    print()

    if failed == 0:
        print("✓ All tests PASSED")
        print()
        print("EXEC CAPABILITY VERIFIED:")
        print("  - Command execution works")
        print("  - Exit codes returned correctly")
        print("  - Output captured successfully")
        print("  - Authorization enforced")
        return True
    else:
        print("✗ Some tests FAILED")
        print()
        print("TROUBLESHOOTING:")
        print("  1. Verify 'echo' is in command allowlist (auth.yaml)")
        print("  2. Check device logs: journalctl -u styrene-agent -f")
        print("  3. Verify authorization: identity must have 'exec' permission")
        return False


def main():
    """Main entry point."""
    if len(sys.argv) != 2:
        print("Usage: ./test_exec.py <DEVICE_HASH>")
        print()
        print("Get device hash from device:")
        print("  rnstatus -i")
        sys.exit(1)

    device_hash = sys.argv[1]

    try:
        success = asyncio.run(test_exec(device_hash))
        sys.exit(0 if success else 1)
    except KeyboardInterrupt:
        print("\nInterrupted")
        sys.exit(1)


if __name__ == "__main__":
    main()
