#!/usr/bin/env python3

import os
import json
import yaml
import subprocess
import sys
import time
from pathlib import Path

def load_package_config():
    """Load the package configuration from aur-packages.yml"""
    with open('aur-packages.yml', 'r') as f:
        config = yaml.safe_load(f)
    return config['packages']

def test_package_build(package_name):
    """Test building a package with paru and return results."""
    print(f"\n=== Testing build for package: {package_name} ===")
    
    # Build result details
    result = {
        "package": package_name,
        "success": False,
        "error": "",
        "log": ""
    }
    
    # Create a temp directory for the build
    temp_dir = f"/tmp/aur-build-test-{package_name}"
    os.makedirs(temp_dir, exist_ok=True)
    
    # Log all output for debugging
    log_output = f"=== Build test for {package_name} ===\n\n"
    
    try:
        # 1. Clone the AUR package
        log_output += "=== Cloning AUR package ===\n"
        clone_proc = subprocess.run(
            ['git', 'clone', f'https://aur.archlinux.org/{package_name}.git'],
            cwd=temp_dir,
            capture_output=True,
            text=True,
            check=False
        )
        
        log_output += f"STDOUT:\n{clone_proc.stdout}\n\nSTDERR:\n{clone_proc.stderr}\n\n"
        
        if clone_proc.returncode != 0:
            result["error"] = f"Failed to clone package with exit code {clone_proc.returncode}"
            result["log"] = log_output
            return result
        
        # 2. Extract dependencies from PKGBUILD
        log_output += "=== Extracting dependencies from PKGBUILD ===\n"
        extract_deps_cmd = 'source ./PKGBUILD && echo "${depends[@]} ${makedepends[@]}"'
        extract_proc = subprocess.run(
            extract_deps_cmd,
            cwd=os.path.join(temp_dir, package_name),
            capture_output=True,
            text=True,
            shell=True,
            check=False
        )
        
        dependencies = extract_proc.stdout.strip()
        log_output += f"Dependencies: {dependencies}\n\n"
        
        # Skip dependency installation if none are found
        if dependencies:
            # 3. Install dependencies with paru
            log_output += "=== Installing dependencies with paru ===\n"
            deps_proc = subprocess.run(
                ['paru', '-S', '--noconfirm', '--asdeps', '--needed'] + dependencies.split(),
                capture_output=True,
                text=True,
                check=False
            )
            
            log_output += f"STDOUT:\n{deps_proc.stdout}\n\nSTDERR:\n{deps_proc.stderr}\n\n"
        
        # 4. Now build the package with makepkg
        log_output += "=== Building package with makepkg ===\n"
        build_proc = subprocess.run(
            ['makepkg', '-f', '--noconfirm'],  # -f forces rebuild, removed -s since we installed deps already
            cwd=os.path.join(temp_dir, package_name),
            capture_output=True,
            text=True,
            check=False
        )
        
        # Check build result
        if build_proc.returncode == 0:
            result["success"] = True
            log_output += "Build successful!\n"
            print(f"✅ Package {package_name} built successfully!")
        else:
            result["success"] = False
            result["error"] = f"Build failed with exit code {build_proc.returncode}"
            
            # Look for common error patterns
            if "One or more files did not pass the validity check!" in build_proc.stderr or "One or more files did not pass the validity check!" in build_proc.stdout:
                result["error"] = "Checksum validation failed"
            elif "target not found" in build_proc.stderr or "target not found" in build_proc.stdout:
                result["error"] = "Dependency not found"
            
            log_output += f"Build failed: {result['error']}\n"
            print(f"❌ Package {package_name} build failed: {result['error']}")
        
    except Exception as e:
        result["success"] = False
        result["error"] = str(e)
        log_output += f"Exception occurred: {str(e)}\n"
        print(f"❌ Package {package_name} build test raised exception: {str(e)}")
    
    # Clean up temp directory to save space
    try:
        subprocess.run(['rm', '-rf', temp_dir], check=False)
    except:
        pass
    
    # Save the complete log
    result["log"] = log_output
    return result

def write_results(results):
    """Write test results to a JSON file."""
    # Create a directory for the logs
    logs_dir = Path("package_build_logs")
    logs_dir.mkdir(exist_ok=True)
    
    # Write individual log files for each package
    for result in results:
        log_file = logs_dir / f"{result['package']}_build.log"
        with open(log_file, 'w') as f:
            f.write(result["log"])
        
        # Remove the log from the result to avoid duplication
        log_entry = result.pop("log")
        
        # Add a reference to the log file
        result["log_file"] = str(log_file)
    
    # Write the summary results file
    with open('package_build_results.json', 'w') as f:
        json.dump(results, f, indent=2)
    
    print(f"\nWritten detailed logs to {logs_dir}/")
    print(f"Written summary results to package_build_results.json")

def main():
    # Get package configuration
    package_configs = load_package_config()
    
    # Get packages to test from command line or use all configured packages
    if len(sys.argv) > 1:
        packages_to_test = sys.argv[1:]
        # Check if all packages exist in config
        for pkg in packages_to_test:
            if pkg not in package_configs:
                print(f"Warning: {pkg} not found in configuration. Testing anyway.")
    else:
        packages_to_test = list(package_configs.keys())
    
    # Store all results
    all_results = []
    failed_count = 0
    
    # Test each package
    for pkg_name in packages_to_test:
        # Add a delay between package builds to avoid issues
        if all_results:  # Not the first package
            print("Waiting 5 seconds before next package build...")
            time.sleep(5)
        
        result = test_package_build(pkg_name)
        all_results.append(result)
        
        if not result["success"]:
            failed_count += 1
    
    # Write results to file
    write_results(all_results)
    
    # Print summary
    print(f"\n=== Build Test Summary ===")
    print(f"Total packages tested: {len(all_results)}")
    print(f"Successful builds: {len(all_results) - failed_count}")
    print(f"Failed builds: {failed_count}")
    
    # Set exit code based on success
    if failed_count > 0:
        print("\nSome package builds failed. Check package_build_results.json for details.")
        sys.exit(1)
    else:
        print("\nAll package builds succeeded!")
        sys.exit(0)

if __name__ == "__main__":
    main() 