#!/usr/bin/env python3
"""
Hotel MCP - Distribution Testing Script

Tests NPX distribution functionality and validates all components
work correctly in different environments.
"""

import json
import os
import subprocess
import sys
import tempfile
from pathlib import Path


def run_command(cmd, cwd=None, capture_output=True):
    """Run a command and return result."""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            cwd=cwd,
            capture_output=capture_output,
            text=True,
            timeout=30,
        )
        return result.returncode == 0, result.stdout, result.stderr
    except subprocess.TimeoutExpired:
        return False, "", "Command timed out"
    except Exception as e:
        return False, "", str(e)


def test_package_json():
    """Test package.json validity."""
    print("🧪 Testing package.json...")

    package_file = Path("package.json")
    if not package_file.exists():
        print("❌ package.json not found")
        return False

    try:
        with open(package_file) as f:
            package_data = json.load(f)

        required_fields = ["name", "version", "bin", "main"]
        for field in required_fields:
            if field not in package_data:
                print(f"❌ Missing required field: {field}")
                return False

        # Check bin script exists
        bin_script = package_data["bin"]["hotel-mcp"]
        if not Path(bin_script).exists():
            print(f"❌ Bin script not found: {bin_script}")
            return False

        print("✅ package.json is valid")
        return True

    except json.JSONDecodeError as e:
        print(f"❌ Invalid JSON: {e}")
        return False


def test_bin_script():
    """Test the bin script functionality."""
    print("🧪 Testing bin script...")

    bin_script = Path("bin/hotel-mcp.js")
    if not bin_script.exists():
        print("❌ Bin script not found")
        return False

    # Test script is executable
    if not os.access(bin_script, os.X_OK):
        print("❌ Bin script is not executable")
        return False

    # Test Node.js syntax
    success, stdout, stderr = run_command(f"node -c {bin_script}")
    if not success:
        print(f"❌ Syntax error in bin script: {stderr}")
        return False

    print("✅ Bin script is valid")
    return True


def test_npm_pack():
    """Test npm pack functionality."""
    print("🧪 Testing npm pack...")

    success, stdout, stderr = run_command("npm pack --dry-run")
    if not success:
        print(f"❌ npm pack failed: {stderr}")
        return False

    print("✅ npm pack successful")
    return True


def test_local_installation():
    """Test local NPX installation."""
    print("🧪 Testing local NPX installation...")

    # Create temporary directory for testing
    with tempfile.TemporaryDirectory() as temp_dir:
        temp_path = Path(temp_dir)

        # Copy essential files for testing
        project_root = Path.cwd()
        essential_files = [
            "package.json",
            "bin/hotel-mcp.js",
            "scripts/postinstall.js",
            "scripts/preuninstall.js",
            "hotel_mcp.py",
            "pyproject.toml",
        ]

        for file_path in essential_files:
            src = project_root / file_path
            if src.exists():
                dst = temp_path / file_path
                dst.parent.mkdir(parents=True, exist_ok=True)

                if src.is_file():
                    dst.write_text(src.read_text())
                    if file_path.endswith(".js"):
                        os.chmod(dst, 0o755)

        # Test npm install
        success, stdout, stderr = run_command("npm install", cwd=temp_path)
        if not success:
            print(f"❌ npm install failed: {stderr}")
            return False

        print("✅ Local installation successful")
        return True


def test_environment_detection():
    """Test environment detection logic."""
    print("🧪 Testing environment detection...")

    # Test with help flag (should be fast and not timeout)
    success, stdout, stderr = run_command("node bin/hotel-mcp.js --help")

    # Check if help message is displayed correctly
    if "Hotel MCP Server" in stdout and "Usage:" in stdout:
        print("✅ Environment detection working")
        return True
    elif "Error:" in stderr and "hotel_mcp.py" in stderr:
        # Expected error when server file not found in test environment
        print("✅ Environment detection working (expected error)")
        return True
    else:
        print(f"❌ Unexpected output: stdout='{stdout}' stderr='{stderr}'")
        return False


def test_python_requirements():
    """Test Python environment requirements."""
    print("🧪 Testing Python requirements...")

    # Check Python version
    success, stdout, stderr = run_command("python3 --version")
    if not success:
        print("❌ Python 3 not available")
        return False

    version_line = stdout.strip()
    if "Python 3." not in version_line:
        print(f"❌ Invalid Python version: {version_line}")
        return False

    # Extract version number
    try:
        version_str = version_line.split()[1]
        major, minor = map(int, version_str.split(".")[:2])
        if major < 3 or (major == 3 and minor < 10):
            print(f"❌ Python version too old: {version_str} (need 3.10+)")
            return False
    except (IndexError, ValueError):
        print(f"❌ Could not parse Python version: {version_line}")
        return False

    print(f"✅ Python version OK: {version_line}")
    return True


def test_project_structure():
    """Test project structure for distribution."""
    print("🧪 Testing project structure...")

    required_files = [
        "hotel_mcp.py",
        "pyproject.toml",
        "package.json",
        "bin/hotel-mcp.js",
        "README.md",
    ]

    for file_path in required_files:
        if not Path(file_path).exists():
            print(f"❌ Missing required file: {file_path}")
            return False

    required_dirs = ["src", "bin", "scripts"]

    for dir_path in required_dirs:
        if not Path(dir_path).is_dir():
            print(f"❌ Missing required directory: {dir_path}")
            return False

    print("✅ Project structure is valid")
    return True


def main():
    """Run all distribution tests."""
    print("🏨 Hotel MCP - Distribution Testing")
    print("=" * 50)

    tests = [
        ("Project Structure", test_project_structure),
        ("Python Requirements", test_python_requirements),
        ("package.json", test_package_json),
        ("Bin Script", test_bin_script),
        ("Environment Detection", test_environment_detection),
        ("NPM Pack", test_npm_pack),
        ("Local Installation", test_local_installation),
    ]

    passed = 0
    total = len(tests)

    for test_name, test_func in tests:
        print(f"\n📋 {test_name}:")
        try:
            if test_func():
                passed += 1
            else:
                print(f"❌ {test_name} failed")
        except Exception as e:
            print(f"❌ {test_name} error: {e}")

    print("\n" + "=" * 50)
    print(f"📊 Results: {passed}/{total} tests passed")

    if passed == total:
        print("🎉 All distribution tests passed!")
        print("✅ Ready for NPX distribution")
        return True
    else:
        print("❌ Some tests failed. Please fix issues before distribution.")
        return False


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