"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeInstaller = makeInstaller;
const logger_1 = require("../../utils/logger");
const modifications_service_1 = require("../modifications/modifications.service");
const os_1 = require("os");
const prerequisites_1 = require("./prerequisites");
const app_service_1 = __importDefault(require("../app.service"));
const components_service_1 = __importDefault(require("../components/components.service"));
const electronForge_1 = require("./electronForge");
const colors_1 = require("../../utils/colors");
const path_1 = require("../../utils/path");
const path_2 = require("path");
const promises_1 = require("fs/promises");
const fs_extra_1 = require("fs-extra");
const config_service_1 = require("../config/config.service");
// Conditionally import macOS helper only on macOS
let macOSInstallerHelper = null;
if (process.platform === 'darwin') {
    try {
        macOSInstallerHelper = require('./macOS.helper');
    }
    catch (error) {
        // Will be handled later when needed
    }
}
// Conditionally import windows helper only on Windows
let windowsHelper = null;
if (process.platform === 'win32') {
    try {
        windowsHelper = require('./windows.helper');
    }
    catch (error) {
        // Will be handled later when needed
    }
}
const logger = logger_1.Logger.getInstance();
async function makeInstaller(_options) {
    logger.info('Creating build...');
    if (_options.skipBuild) {
        logger.info('Skipping build steps as per --skip-build option');
    }
    if (!_options.skipBuild) {
        // Check prerequisites
        await (0, prerequisites_1.validatePrerequisites)(['@electron-forge/core']);
        // Reinstall components to ensure clean state (dev mode modifications might have altered components)
        // Only install components that should be included in the build (respects excludeFromBuild)
        await components_service_1.default.installComponentsForBuild();
        // Build all apps to ensure latest code; this must be done before applying modifications
        await app_service_1.default.buildAllApps();
        // apply modifications before signing and packaging
        await (0, modifications_service_1.applyModifications)("build");
        await moveComponentsToIOCDFolder();
        // sign executables
        await sign();
    }
    // Create package using electron-builder
    const { published } = await (0, electronForge_1.createPackageWithElectronForge)();
    logger.info((0, colors_1.green)(`✨ Build created ${published ? 'and published' : ''} successfully!`));
}
async function sign() {
    if ((0, os_1.platform)() === 'darwin') {
        if (!macOSInstallerHelper) {
            logger.error('macOS build helper module is required but not available');
            throw new Error('macOS build helper module is required but not available');
        }
        // Sign and notarize if macOS
        await macOSInstallerHelper.signAndNotarizeMacOS();
    }
    else if ((0, os_1.platform)() === 'win32') {
        if (!windowsHelper) {
            logger.error('Windows build helper module is required but not available');
            throw new Error('Windows build helper module is required but not available');
        }
        await windowsHelper.signIOCDBinaries();
    }
}
async function moveComponentsToIOCDFolder() {
    // move all components (except iocd) to iocd/components folder
    // components are located in components folder
    const componentsDir = path_1.PathUtils.getComponentsDir();
    const iocdDir = path_1.PathUtils.getIOCDDir();
    const iocdComponentsDir = (0, path_2.join)(iocdDir, 'components');
    logger.debug(`Copying components from ${componentsDir} to ${iocdComponentsDir}`);
    // Get list of components to exclude from build
    const excludeFromBuild = config_service_1.ConfigManager.config.components.excludeFromBuild || [];
    logger.debug(`Components excluded from build: ${excludeFromBuild.join(', ')}`);
    try {
        // remove existing components folder if exists
        if (await (0, fs_extra_1.pathExists)(iocdComponentsDir)) {
            logger.debug('Removing existing iocd/components folder...');
            await (0, fs_extra_1.remove)(iocdComponentsDir);
            logger.debug('Existing iocd/components folder removed.');
        }
        await (0, fs_extra_1.ensureDir)(iocdComponentsDir);
        const items = await (0, promises_1.readdir)(componentsDir);
        for (const item of items) {
            if (item === 'iocd') {
                continue; // skip iocd itself
            }
            // Skip components that are excluded from build
            if (excludeFromBuild.includes(item)) {
                logger.debug(`Skipping component '${item}' - excluded from build`);
                continue;
            }
            const srcPath = (0, path_2.join)(componentsDir, item);
            const destPath = (0, path_2.join)(iocdComponentsDir, item);
            logger.debug(`Copying ${srcPath} to ${destPath}....`);
            await (0, promises_1.cp)(srcPath, destPath, { recursive: true, force: true });
            logger.debug(`Copied ${item} successfully.`);
        }
        logger.debug('All components copied successfully.');
    }
    catch (error) {
        logger.error(`Failed to copy components: ${error}`);
        throw error;
    }
}
//# sourceMappingURL=installer.service.js.map