#!/usr/bin/env python3
"""
Simple OSTree Boot Test for Debian bootc-image-builder

This script tests basic OSTree boot process integration.

Author: Debian bootc-image-builder team
License: Same as original bootc-image-builder
"""

import os
import sys
import subprocess
import tempfile
import shutil
from typing import Dict, List, Optional, Any
import logging

# Add the parent directory to the path to import the kernel stage
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from debian_kernel_stage import DebianKernelStage

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class OSTreeBootTest:
    """
    Test class for basic OSTree boot process validation.
    """
    
    def __init__(self):
        self.test_results = {}
        self.temp_dirs = []
    
    def _setup_mock_kernel_files(self, test_dir: str) -> Dict[str, str]:
        """Set up mock kernel files for testing."""
        kernel_version = '6.1.0-13-amd64'
        kernel_path = f'{test_dir}/boot/vmlinuz-{kernel_version}'
        initramfs_path = f'{test_dir}/boot/initrd.img-{kernel_version}'
        modules_path = f'{test_dir}/usr/lib/modules/{kernel_version}'
        
        # Create directories and files
        os.makedirs(os.path.dirname(kernel_path), exist_ok=True)
        os.makedirs(os.path.dirname(initramfs_path), exist_ok=True)
        os.makedirs(modules_path, exist_ok=True)
        
        # Create mock files
        with open(kernel_path, 'w') as f:
            f.write("mock kernel")
        with open(initramfs_path, 'w') as f:
            f.write("mock initramfs")
        
        return {
            'kernel_version': kernel_version,
            'kernel_path': kernel_path,
            'modules_path': modules_path
        }
    
    def run_all_tests(self) -> bool:
        """Run all OSTree boot tests."""
        logger.info("Starting OSTree boot process tests")
        
        tests = [
            ("test_basic_ostree_integration", self.test_basic_ostree_integration),
        ]
        
        all_passed = True
        
        for test_name, test_func in tests:
            logger.info(f"Running test: {test_name}")
            try:
                result = test_func()
                self.test_results[test_name] = result
                if result:
                    logger.info(f"✓ {test_name} PASSED")
                else:
                    logger.error(f"✗ {test_name} FAILED")
                    all_passed = False
            except Exception as e:
                logger.error(f"✗ {test_name} FAILED with exception: {e}")
                self.test_results[test_name] = False
                all_passed = False
        
        self.print_summary()
        return all_passed
    
    def test_basic_ostree_integration(self) -> bool:
        """Test basic OSTree integration."""
        logger.info("Testing basic OSTree integration")
        
        try:
            # Create test directory structure
            test_dir = tempfile.mkdtemp(prefix="ostree_basic_test_")
            self.temp_dirs.append(test_dir)
            
            # Create mock context
            context = MockOsbuildContext(test_dir)
            
            # Test kernel stage
            options = {
                'kernel_package': 'linux-image-amd64',
                'ostree_integration': True
            }
            
            kernel_stage = DebianKernelStage(options)
            
            # Set up mock kernel files
            kernel_info = self._setup_mock_kernel_files(test_dir)
            
            # Test OSTree integration setup
            kernel_stage._setup_ostree_integration(context, kernel_info)
            
            # Check if OSTree configuration was created
            ostree_config = f"{test_dir}/etc/ostree/ostree.conf"
            if not os.path.exists(ostree_config):
                logger.error("OSTree configuration not created")
                return False
            
            # Check if OSTree boot directory was created
            ostree_boot_dir = f"{test_dir}/usr/lib/ostree-boot"
            if not os.path.exists(ostree_boot_dir):
                logger.error("OSTree boot directory not created")
                return False
            
            # Check if kernel file was copied
            kernel_file = f"{ostree_boot_dir}/vmlinuz"
            if not os.path.exists(kernel_file):
                logger.error("Kernel file not found in OSTree boot directory")
                return False
            
            logger.info("Basic OSTree integration successful")
            return True
            
        except Exception as e:
            logger.error(f"Basic OSTree integration test failed: {e}")
            return False
    
    def print_summary(self):
        """Print test summary."""
        logger.info("=" * 50)
        logger.info("OSTREE BOOT PROCESS TEST SUMMARY")
        logger.info("=" * 50)
        
        passed = sum(1 for result in self.test_results.values() if result)
        total = len(self.test_results)
        
        for test_name, result in self.test_results.items():
            status = "PASSED" if result else "FAILED"
            logger.info(f"{test_name}: {status}")
        
        logger.info(f"Overall: {passed}/{total} tests passed")
        logger.info("=" * 50)
    
    def cleanup(self):
        """Clean up temporary directories."""
        for temp_dir in self.temp_dirs:
            try:
                shutil.rmtree(temp_dir)
            except Exception as e:
                logger.warning(f"Failed to clean up {temp_dir}: {e}")


class MockOsbuildContext:
    """Mock osbuild context for testing."""
    
    def __init__(self, root_path: str):
        self.root_path = root_path
        self.root = root_path
    
    def run(self, cmd: List[str], **kwargs) -> subprocess.CompletedProcess:
        """Mock run method that simulates osbuild context execution."""
        logger.info(f"Mock context executing: {' '.join(cmd)}")
        
        result = subprocess.CompletedProcess(
            args=cmd,
            returncode=0,
            stdout=b"mock output",
            stderr=b""
        )
        
        return result


def main():
    """Main function to run the tests."""
    logger.info("Starting OSTree boot process tests")
    
    test_runner = OSTreeBootTest()
    
    try:
        success = test_runner.run_all_tests()
        
        if success:
            logger.info("All OSTree boot process tests PASSED")
            sys.exit(0)
        else:
            logger.error("Some OSTree boot process tests FAILED")
            sys.exit(1)
            
    finally:
        test_runner.cleanup()


if __name__ == "__main__":
    main()
