import { SimulatorBoot } from './SimulatorBoot.js';
import { SimulatorApps } from './SimulatorApps.js';
import { SimulatorUI } from './SimulatorUI.js';
import { SimulatorInfo } from './SimulatorInfo.js';
import { SimulatorReset } from './SimulatorReset.js';
import { createModuleLogger } from '../../logger.js';
const logger = createModuleLogger('SimulatorDevice');
/**
 * Represents a specific simulator device instance.
 * Provides a complete interface for simulator operations while
 * delegating to specialized components internally.
 */
export class SimulatorDevice {
    id;
    name;
    platform;
    runtime;
    boot;
    apps;
    ui;
    info;
    reset;
    constructor(id, name, platform, runtime, components) {
        this.id = id;
        this.name = name;
        this.platform = platform;
        this.runtime = runtime;
        this.boot = components?.boot || new SimulatorBoot();
        this.apps = components?.apps || new SimulatorApps();
        this.ui = components?.ui || new SimulatorUI();
        this.info = components?.info || new SimulatorInfo();
        this.reset = components?.reset || new SimulatorReset();
    }
    /**
     * Boot this simulator device
     */
    async bootDevice() {
        logger.debug({ deviceId: this.id, name: this.name }, 'Booting device');
        await this.boot.boot(this.id);
    }
    /**
     * Shutdown this simulator device
     */
    async shutdown() {
        logger.debug({ deviceId: this.id, name: this.name }, 'Shutting down device');
        await this.boot.shutdown(this.id);
    }
    /**
     * Install an app on this device
     */
    async install(appPath) {
        logger.debug({ deviceId: this.id, appPath }, 'Installing app on device');
        await this.apps.install(appPath, this.id);
    }
    /**
     * Uninstall an app from this device
     */
    async uninstall(bundleId) {
        logger.debug({ deviceId: this.id, bundleId }, 'Uninstalling app from device');
        await this.apps.uninstall(bundleId, this.id);
    }
    /**
     * Launch an app on this device
     */
    async launch(bundleId) {
        logger.debug({ deviceId: this.id, bundleId }, 'Launching app on device');
        return await this.apps.launch(bundleId, this.id);
    }
    /**
     * Get bundle ID from an app path
     */
    async getBundleId(appPath) {
        return await this.apps.getBundleId(appPath);
    }
    /**
     * Take a screenshot of this device
     */
    async screenshot(outputPath) {
        logger.debug({ deviceId: this.id, outputPath }, 'Taking screenshot');
        await this.ui.screenshot(outputPath, this.id);
    }
    /**
     * Get screenshot data as base64
     */
    async screenshotData() {
        logger.debug({ deviceId: this.id }, 'Getting screenshot data');
        return await this.ui.screenshotData(this.id);
    }
    /**
     * Set appearance mode (light/dark)
     */
    async setAppearance(appearance) {
        logger.debug({ deviceId: this.id, appearance }, 'Setting appearance');
        await this.ui.setAppearance(appearance, this.id);
    }
    /**
     * Open the Simulator app UI
     */
    async open() {
        await this.ui.open();
    }
    /**
     * Get device logs
     */
    async logs(predicate, last) {
        logger.debug({ deviceId: this.id, predicate, last }, 'Getting device logs');
        return await this.info.logs(this.id, predicate, last);
    }
    /**
     * Get current device state
     */
    async getState() {
        return await this.info.getDeviceState(this.id);
    }
    /**
     * Check if device is available
     */
    async checkAvailability() {
        return await this.info.isAvailable(this.id);
    }
    /**
     * Reset this device to clean state
     */
    async resetDevice() {
        logger.debug({ deviceId: this.id, name: this.name }, 'Resetting device');
        await this.reset.reset(this.id);
    }
    /**
     * Check if device is currently booted
     * Checks actual current state, not cached value
     */
    async isBooted() {
        const currentState = await this.getState();
        return currentState === 'Booted';
    }
    /**
     * Ensure this device is booted, boot if necessary
     */
    async ensureBooted() {
        // Check if device is available before trying to boot
        const available = await this.checkAvailability();
        if (!available) {
            throw new Error(`Device "${this.name}" (${this.id}) is not available. ` +
                `The runtime "${this.runtime}" may be missing or corrupted. ` +
                `Try downloading the runtime in Xcode or use a different simulator.`);
        }
        // Use the async isBooted() method to check actual state
        if (!(await this.isBooted())) {
            await this.bootDevice();
        }
        else {
            logger.debug({ deviceId: this.id, name: this.name }, 'Device already booted');
        }
    }
}
//# sourceMappingURL=SimulatorDevice.js.map