import { execSync } from 'child_process';
import { createModuleLogger } from '../../logger';
const logger = createModuleLogger('TestEnvironmentCleaner');
/**
 * Utility class for cleaning up test environment (simulators, processes, etc.)
 * Separate from TestProjectManager to maintain single responsibility
 */
export class TestEnvironmentCleaner {
    /**
     * Shutdown all running simulators
     * Faster than erasing simulators, just powers them off
     */
    static shutdownAllSimulators() {
        try {
            execSync('xcrun simctl shutdown all', { stdio: 'ignore' });
        }
        catch (error) {
            logger.debug('No simulators to shutdown or shutdown failed (normal)');
        }
    }
    /**
     * Kill a running macOS app by name
     * @param appName Name of the app process to kill
     */
    static killMacOSApp(appName) {
        try {
            execSync(`pkill -f ${appName}`, { stdio: 'ignore' });
        }
        catch (error) {
            // Ignore errors - app might not be running
        }
    }
    /**
     * Kill the test project app if it's running on macOS
     */
    static killTestProjectApp() {
        this.killMacOSApp('TestProjectXCTest');
    }
    /**
     * Clean DerivedData and SPM build artifacts for test projects
     */
    static cleanDerivedData() {
        try {
            // Clean MCP-Xcode DerivedData location (where our tests actually write)
            // This includes Logs/Test/*.xcresult files
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestProjectSwiftTesting', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestProjectXCTest', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestSwiftPackage*', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            // Also clean standard Xcode DerivedData locations (in case xcodebuild uses them directly)
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestProjectSwiftTesting-*', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestProjectXCTest-*', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestSwiftPackage-*', {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            // Clean SPM .build directories in test artifacts
            const testArtifactsDir = process.cwd() + '/test_artifacts';
            execSync(`find ${testArtifactsDir} -name .build -type d -exec rm -rf {} + 2>/dev/null || true`, {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
            // Clean .swiftpm directories
            execSync(`find ${testArtifactsDir} -name .swiftpm -type d -exec rm -rf {} + 2>/dev/null || true`, {
                shell: '/bin/bash',
                stdio: 'ignore'
            });
        }
        catch (error) {
            logger.debug('DerivedData cleanup failed or nothing to clean (normal)');
        }
    }
    /**
     * Full cleanup of test environment
     * Shuts down simulators, kills test apps, and cleans DerivedData
     */
    static cleanupTestEnvironment() {
        // Shutdown all simulators
        this.shutdownAllSimulators();
        // Kill any running test apps
        this.killTestProjectApp();
        // Clean DerivedData for test projects
        this.cleanDerivedData();
    }
    /**
     * Reset a specific simulator by erasing its contents
     * @param deviceId The simulator device ID to reset
     */
    static resetSimulator(deviceId) {
        try {
            execSync(`xcrun simctl erase "${deviceId}"`);
        }
        catch (error) {
            // Log the actual error message for debugging
            logger.warn({ deviceId, error: error.message, stderr: error.stderr?.toString() }, 'Failed to erase simulator');
        }
    }
    /**
     * Boot a specific simulator
     * @param deviceId The simulator device ID to boot
     */
    static bootSimulator(deviceId) {
        try {
            execSync(`xcrun simctl boot "${deviceId}"`, { stdio: 'ignore' });
        }
        catch (error) {
            logger.warn({ deviceId }, 'Simulator already booted or boot failed');
        }
    }
}
//# sourceMappingURL=TestEnvironmentCleaner.js.map