#!/usr/bin/env python3
"""
Test Modal Terminal Tool

This script tests that the Modal terminal backend is correctly configured
and can execute commands in Modal sandboxes.

Usage:
    # Run with Modal backend
    TERMINAL_ENV=modal python tests/test_modal_terminal.py

    # Or run directly (will use whatever TERMINAL_ENV is set in .env)
    python tests/test_modal_terminal.py
"""

import pytest
pytestmark = pytest.mark.integration

import os
import sys
import json
from pathlib import Path

# Try to load .env file if python-dotenv is available
try:
    from dotenv import load_dotenv
    load_dotenv()
except ImportError:
    # Manually load .env if dotenv not available
    env_file = Path(__file__).parent.parent.parent / ".env"
    if env_file.exists():
        with open(env_file) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#') and '=' in line:
                    key, value = line.split('=', 1)
                    # Remove quotes if present
                    value = value.strip().strip('"').strip("'")
                    os.environ.setdefault(key.strip(), value)

# Add project root to path for imports
parent_dir = Path(__file__).parent.parent.parent
sys.path.insert(0, str(parent_dir))

# Import terminal_tool module directly using importlib to avoid tools/__init__.py
import importlib.util
terminal_tool_path = parent_dir / "tools" / "terminal_tool.py"
spec = importlib.util.spec_from_file_location("terminal_tool", terminal_tool_path)
terminal_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(terminal_module)

terminal_tool = terminal_module.terminal_tool
check_terminal_requirements = terminal_module.check_terminal_requirements
_get_env_config = terminal_module._get_env_config
cleanup_vm = terminal_module.cleanup_vm


def test_modal_requirements():
    """Test that Modal requirements are met."""
    print("\n" + "=" * 60)
    print("TEST 1: Modal Requirements Check")
    print("=" * 60)
    
    config = _get_env_config()
    print(f"Current TERMINAL_ENV: {config['env_type']}")
    print(f"Modal image: {config['modal_image']}")
    
    # Check for Modal authentication
    modal_token = os.getenv("MODAL_TOKEN_ID")
    modal_toml = Path.home() / ".modal.toml"
    
    print(f"\nModal authentication:")
    print(f"  MODAL_TOKEN_ID env var: {'✅ Set' if modal_token else '❌ Not set'}")
    print(f"  ~/.modal.toml file: {'✅ Exists' if modal_toml.exists() else '❌ Not found'}")
    
    if config['env_type'] != 'modal':
        print(f"\n⚠️  TERMINAL_ENV is '{config['env_type']}', not 'modal'")
        print("   Set TERMINAL_ENV=modal in .env or export it to test Modal backend")
        return False
    
    requirements_met = check_terminal_requirements()
    print(f"\nRequirements check: {'✅ Passed' if requirements_met else '❌ Failed'}")
    
    return requirements_met


def test_simple_command():
    """Test executing a simple command."""
    print("\n" + "=" * 60)
    print("TEST 2: Simple Command Execution")
    print("=" * 60)
    
    test_task_id = "modal_test_simple"
    
    print("Executing: echo 'Hello from Modal!'")
    result = terminal_tool("echo 'Hello from Modal!'", task_id=test_task_id)
    result_json = json.loads(result)
    
    print(f"\nResult:")
    print(f"  Output: {result_json.get('output', '')[:200]}")
    print(f"  Exit code: {result_json.get('exit_code')}")
    print(f"  Error: {result_json.get('error')}")
    
    success = result_json.get('exit_code') == 0 and 'Hello from Modal!' in result_json.get('output', '')
    print(f"\nTest: {'✅ Passed' if success else '❌ Failed'}")
    
    # Cleanup
    cleanup_vm(test_task_id)
    
    return success


def test_python_execution():
    """Test executing Python code in Modal."""
    print("\n" + "=" * 60)
    print("TEST 3: Python Execution")
    print("=" * 60)
    
    test_task_id = "modal_test_python"
    
    python_cmd = 'python3 -c "import sys; print(f\'Python {sys.version}\')"'
    print(f"Executing: {python_cmd}")
    
    result = terminal_tool(python_cmd, task_id=test_task_id)
    result_json = json.loads(result)
    
    print(f"\nResult:")
    print(f"  Output: {result_json.get('output', '')[:200]}")
    print(f"  Exit code: {result_json.get('exit_code')}")
    print(f"  Error: {result_json.get('error')}")
    
    success = result_json.get('exit_code') == 0 and 'Python' in result_json.get('output', '')
    print(f"\nTest: {'✅ Passed' if success else '❌ Failed'}")
    
    # Cleanup
    cleanup_vm(test_task_id)
    
    return success


def test_pip_install():
    """Test installing a package with pip in Modal."""
    print("\n" + "=" * 60)
    print("TEST 4: Pip Install Test")
    print("=" * 60)
    
    test_task_id = "modal_test_pip"
    
    # Install a small package and verify
    print("Executing: pip install --break-system-packages cowsay && python3 -c \"import cowsay; cowsay.cow('Modal works!')\"")
    
    result = terminal_tool(
        "pip install --break-system-packages cowsay && python3 -c \"import cowsay; cowsay.cow('Modal works!')\"",
        task_id=test_task_id,
        timeout=120
    )
    result_json = json.loads(result)
    
    print(f"\nResult:")
    output = result_json.get('output', '')
    print(f"  Output (last 500 chars): ...{output[-500:] if len(output) > 500 else output}")
    print(f"  Exit code: {result_json.get('exit_code')}")
    print(f"  Error: {result_json.get('error')}")
    
    success = result_json.get('exit_code') == 0 and 'Modal works!' in result_json.get('output', '')
    print(f"\nTest: {'✅ Passed' if success else '❌ Failed'}")
    
    # Cleanup
    cleanup_vm(test_task_id)
    
    return success


def test_filesystem_persistence():
    """Test that filesystem persists between commands in the same task."""
    print("\n" + "=" * 60)
    print("TEST 5: Filesystem Persistence")
    print("=" * 60)
    
    test_task_id = "modal_test_persist"
    
    # Create a file
    print("Step 1: Creating test file...")
    result1 = terminal_tool("echo 'persistence test' > /tmp/modal_test.txt", task_id=test_task_id)
    result1_json = json.loads(result1)
    print(f"  Exit code: {result1_json.get('exit_code')}")
    
    # Read the file back
    print("Step 2: Reading test file...")
    result2 = terminal_tool("cat /tmp/modal_test.txt", task_id=test_task_id)
    result2_json = json.loads(result2)
    print(f"  Output: {result2_json.get('output', '')}")
    print(f"  Exit code: {result2_json.get('exit_code')}")
    
    success = (
        result1_json.get('exit_code') == 0 and
        result2_json.get('exit_code') == 0 and
        'persistence test' in result2_json.get('output', '')
    )
    print(f"\nTest: {'✅ Passed' if success else '❌ Failed'}")
    
    # Cleanup
    cleanup_vm(test_task_id)
    
    return success


def test_environment_isolation():
    """Test that different task_ids get isolated environments."""
    print("\n" + "=" * 60)
    print("TEST 6: Environment Isolation")
    print("=" * 60)
    
    task1 = "modal_test_iso_1"
    task2 = "modal_test_iso_2"
    
    # Create file in task1
    print("Step 1: Creating file in task1...")
    result1 = terminal_tool("echo 'task1 data' > /tmp/isolated.txt", task_id=task1)
    
    # Try to read from task2 (should not exist)
    print("Step 2: Trying to read file from task2 (should not exist)...")
    result2 = terminal_tool("cat /tmp/isolated.txt 2>&1 || echo 'FILE_NOT_FOUND'", task_id=task2)
    result2_json = json.loads(result2)
    
    # The file should either not exist or be empty in task2
    output = result2_json.get('output', '')
    isolated = 'task1 data' not in output or 'FILE_NOT_FOUND' in output or 'No such file' in output
    
    print(f"  Task2 output: {output[:200]}")
    print(f"\nTest: {'✅ Passed (environments isolated)' if isolated else '❌ Failed (environments NOT isolated)'}")
    
    # Cleanup
    cleanup_vm(task1)
    cleanup_vm(task2)
    
    return isolated


def main():
    """Run all Modal terminal tests."""
    print("🧪 Modal Terminal Tool Test Suite")
    print("=" * 60)
    
    # Check current config
    config = _get_env_config()
    print(f"\nCurrent configuration:")
    print(f"  TERMINAL_ENV: {config['env_type']}")
    print(f"  TERMINAL_MODAL_IMAGE: {config['modal_image']}")
    print(f"  TERMINAL_TIMEOUT: {config['timeout']}s")
    
    if config['env_type'] != 'modal':
        print(f"\n⚠️  WARNING: TERMINAL_ENV is set to '{config['env_type']}', not 'modal'")
        print("   To test Modal specifically, set TERMINAL_ENV=modal")
        response = input("\n   Continue testing with current backend? (y/n): ")
        if response.lower() != 'y':
            print("Aborting.")
            return
    
    results = {}
    
    # Run tests
    results['requirements'] = test_modal_requirements()
    
    if not results['requirements']:
        print("\n❌ Requirements not met. Cannot continue with other tests.")
        return
    
    results['simple_command'] = test_simple_command()
    results['python_execution'] = test_python_execution()
    results['pip_install'] = test_pip_install()
    results['filesystem_persistence'] = test_filesystem_persistence()
    results['environment_isolation'] = test_environment_isolation()
    
    # Summary
    print("\n" + "=" * 60)
    print("TEST SUMMARY")
    print("=" * 60)
    
    passed = sum(1 for v in results.values() if v)
    total = len(results)
    
    for test_name, passed_test in results.items():
        status = "✅ PASSED" if passed_test else "❌ FAILED"
        print(f"  {test_name}: {status}")
    
    print(f"\nTotal: {passed}/{total} tests passed")
    
    return passed == total


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)
