#!/usr/bin/env python3
"""
Simple test runner for AIVA-001 tests (no pytest required)

VERIFICATION_STAMP
Story: AIVA-001
Verified By: Claude Opus 4.5
Verified At: 2026-01-26T00:00:00Z
"""

import sys
import os
from pathlib import Path

# Add genesis path
GENESIS_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(GENESIS_ROOT))
sys.path.insert(0, str(GENESIS_ROOT / "data" / "genesis-memory"))

# Track test results
tests_run = 0
tests_passed = 0
tests_failed = 0


def test(name):
    """Decorator to mark test functions."""
    def decorator(func):
        func._is_test = True
        func._test_name = name
        return func
    return decorator


def run_test(func):
    """Run a single test function."""
    global tests_run, tests_passed, tests_failed

    tests_run += 1
    test_name = getattr(func, '_test_name', func.__name__)

    try:
        func()
        print(f"✓ PASS: {test_name}")
        tests_passed += 1
        return True
    except AssertionError as e:
        print(f"✗ FAIL: {test_name}")
        print(f"  Assertion: {str(e)}")
        tests_failed += 1
        return False
    except Exception as e:
        print(f"✗ ERROR: {test_name}")
        print(f"  Exception: {type(e).__name__}: {str(e)}")
        tests_failed += 1
        return False


# ============================================================================
# BLACK-BOX TESTS
# ============================================================================

@test("BLACK-BOX: Config module can be imported")
def test_config_import():
    """Verify config module imports without errors."""
    from AIVA.config import AIVAConfig, get_config
    assert AIVAConfig is not None
    assert get_config is not None


@test("BLACK-BOX: Config has required sections")
def test_config_sections():
    """Verify config has all required sections."""
    from AIVA.config import AIVAConfig

    # Create default config
    config = AIVAConfig()

    # Verify sections exist
    assert hasattr(config, 'postgres')
    assert hasattr(config, 'redis')
    assert hasattr(config, 'qdrant')
    assert hasattr(config, 'task_queue')
    assert hasattr(config, 'models')
    assert hasattr(config, 'autonomy')
    assert hasattr(config, 'health')
    assert hasattr(config, 'logging')


@test("BLACK-BOX: Config can be serialized to dict")
def test_config_serialization():
    """Verify config can be converted to dictionary."""
    from AIVA.config import AIVAConfig

    config = AIVAConfig()
    config_dict = config.to_dict()

    assert isinstance(config_dict, dict)
    assert 'task_queue' in config_dict
    assert 'models' in config_dict
    assert 'autonomy' in config_dict


@test("BLACK-BOX: Health check module imports")
def test_health_check_import():
    """Verify health check module imports without errors."""
    from AIVA.health_check import HealthCheckServer, HealthStatus
    assert HealthCheckServer is not None
    assert HealthStatus is not None


@test("BLACK-BOX: HealthStatus can be created and serialized")
def test_health_status_creation():
    """Verify HealthStatus creation and serialization."""
    from AIVA.health_check import HealthStatus

    status = HealthStatus()
    status.add_check("test", True, "OK")

    result = status.to_dict()
    assert result['overall_healthy'] is True
    assert 'checks' in result
    assert 'test' in result['checks']


@test("BLACK-BOX: Daemon module imports")
def test_daemon_import():
    """Verify daemon module imports without errors."""
    from AIVA.daemon import AIVADaemon, PostgresLogger
    assert AIVADaemon is not None
    assert PostgresLogger is not None


# ============================================================================
# WHITE-BOX TESTS
# ============================================================================

@test("WHITE-BOX: TaskQueueConfig has required fields")
def test_task_queue_config_fields():
    """Verify TaskQueueConfig internal structure."""
    from AIVA.config import TaskQueueConfig

    config = TaskQueueConfig()
    assert hasattr(config, 'max_parallel_tasks')
    assert hasattr(config, 'task_timeout_seconds')
    assert hasattr(config, 'priority_formula')
    assert hasattr(config, 'queue_refresh_interval')
    assert hasattr(config, 'max_queue_size')

    # Verify defaults
    assert config.max_parallel_tasks == 5
    assert config.task_timeout_seconds == 300


@test("WHITE-BOX: ModelConfig has required fields")
def test_model_config_fields():
    """Verify ModelConfig internal structure."""
    from AIVA.config import ModelConfig

    config = ModelConfig()
    assert hasattr(config, 'primary_model')
    assert hasattr(config, 'fallback_model')
    assert hasattr(config, 'reasoning_model')
    assert hasattr(config, 'use_rate_maximizer')
    assert hasattr(config, 'max_tokens')
    assert hasattr(config, 'temperature')

    # Verify defaults
    assert config.primary_model == "gemini-2.0-flash-exp"
    assert config.use_rate_maximizer is True


@test("WHITE-BOX: AutonomyConfig has required fields")
def test_autonomy_config_fields():
    """Verify AutonomyConfig internal structure."""
    from AIVA.config import AutonomyConfig

    config = AutonomyConfig()
    assert hasattr(config, 'level')
    assert hasattr(config, 'auto_commit')
    assert hasattr(config, 'auto_deploy')
    assert hasattr(config, 'auto_spend_limit_usd')
    assert hasattr(config, 'escalation_channels')
    assert hasattr(config, 'require_approval_for')

    # Verify defaults
    assert config.level == 3
    assert config.auto_commit is True
    assert config.auto_deploy is False


@test("WHITE-BOX: HealthConfig has required fields")
def test_health_config_fields():
    """Verify HealthConfig internal structure."""
    from AIVA.config import HealthConfig

    config = HealthConfig()
    assert hasattr(config, 'port')
    assert hasattr(config, 'host')
    assert hasattr(config, 'check_interval_seconds')
    assert hasattr(config, 'timeout_seconds')

    # Verify defaults
    assert config.port == 8765
    assert config.host == "0.0.0.0"


@test("WHITE-BOX: LoggingConfig has required fields")
def test_logging_config_fields():
    """Verify LoggingConfig internal structure."""
    from AIVA.config import LoggingConfig

    config = LoggingConfig()
    assert hasattr(config, 'level')
    assert hasattr(config, 'postgres_log_table')
    assert hasattr(config, 'log_to_stdout')
    assert hasattr(config, 'log_to_postgres')
    assert hasattr(config, 'log_tasks')
    assert hasattr(config, 'log_decisions')

    # Verify defaults
    assert config.level == "INFO"
    assert config.postgres_log_table == "aiva_logs"


@test("WHITE-BOX: HealthStatus tracks overall health")
def test_health_status_tracking():
    """Verify HealthStatus internal health tracking logic."""
    from AIVA.health_check import HealthStatus

    status = HealthStatus()
    assert status.overall_healthy is True

    # Add passing check
    status.add_check("check1", True, "OK")
    assert status.overall_healthy is True

    # Add failing check
    status.add_check("check2", False, "Failed")
    assert status.overall_healthy is False

    # Verify status code
    result = status.to_dict()
    assert result['status_code'] == 503  # Unhealthy


# ============================================================================
# INTEGRATION TESTS
# ============================================================================

@test("INTEGRATION: Config imports Elestio config")
def test_config_elestio_integration():
    """Verify config integrates with Elestio config."""
    from AIVA.config import AIVAConfig

    config = AIVAConfig()

    # Verify Elestio configs are loaded
    assert config.postgres.host is not None
    assert config.redis.host is not None
    assert config.qdrant.url is not None


@test("INTEGRATION: systemd service file exists")
def test_systemd_service_exists():
    """Verify systemd service template was created."""
    service_file = GENESIS_ROOT / "infra" / "aiva.service"
    assert service_file.exists()

    content = service_file.read_text()
    assert "AIVA" in content
    assert "daemon.py" in content
    assert "MemoryMax=4G" in content


@test("INTEGRATION: All required files exist")
def test_all_files_exist():
    """Verify all AIVA-001 files were created."""
    required_files = [
        GENESIS_ROOT / "infra" / "aiva.service",
        GENESIS_ROOT / "AIVA" / "daemon.py",
        GENESIS_ROOT / "AIVA" / "health_check.py",
        GENESIS_ROOT / "AIVA" / "config.py",
        GENESIS_ROOT / "tests" / "test_aiva_daemon.py",
    ]

    for file_path in required_files:
        assert file_path.exists(), f"Missing file: {file_path}"


@test("INTEGRATION: All files have VERIFICATION_STAMP")
def test_verification_stamps():
    """Verify all files have VERIFICATION_STAMP."""
    files_to_check = [
        GENESIS_ROOT / "infra" / "aiva.service",
        GENESIS_ROOT / "AIVA" / "daemon.py",
        GENESIS_ROOT / "AIVA" / "health_check.py",
        GENESIS_ROOT / "AIVA" / "config.py",
        GENESIS_ROOT / "tests" / "test_aiva_daemon.py",
    ]

    for file_path in files_to_check:
        content = file_path.read_text()
        assert "VERIFICATION_STAMP" in content, f"No VERIFICATION_STAMP in {file_path}"
        assert "AIVA-001" in content, f"No Story AIVA-001 in {file_path}"


# ============================================================================
# TEST RUNNER
# ============================================================================

def main():
    """Run all tests and report results."""
    print("=" * 70)
    print("AIVA-001 Test Suite")
    print("=" * 70)
    print()

    # Collect all test functions
    test_functions = [
        (func, func._test_name)
        for name, func in globals().items()
        if callable(func) and hasattr(func, '_is_test')
    ]

    # Run tests by category
    categories = {
        "BLACK-BOX": [],
        "WHITE-BOX": [],
        "INTEGRATION": []
    }

    for func, test_name in test_functions:
        if "BLACK-BOX" in test_name:
            categories["BLACK-BOX"].append(func)
        elif "WHITE-BOX" in test_name:
            categories["WHITE-BOX"].append(func)
        elif "INTEGRATION" in test_name:
            categories["INTEGRATION"].append(func)

    # Run each category
    for category, funcs in categories.items():
        if funcs:
            print(f"\n{category} TESTS ({len(funcs)} tests)")
            print("-" * 70)
            for func in funcs:
                run_test(func)

    # Print summary
    print()
    print("=" * 70)
    print("TEST SUMMARY")
    print("=" * 70)
    print(f"Tests Run:    {tests_run}")
    print(f"Tests Passed: {tests_passed}")
    print(f"Tests Failed: {tests_failed}")
    print(f"Pass Rate:    {(tests_passed/tests_run*100) if tests_run > 0 else 0:.1f}%")
    print()

    if tests_failed == 0:
        print("✓ ALL TESTS PASSED")
        print()
        print("VERIFICATION_STAMP")
        print("Story: AIVA-001")
        print("Tests: {}/{}".format(tests_passed, tests_run))
        print("Coverage: Black-box + White-box + Integration")
        print("Status: PASS")
        return 0
    else:
        print("✗ SOME TESTS FAILED")
        return 1


if __name__ == "__main__":
    sys.exit(main())
