"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");
const license_file_service_1 = require("../license-file.service");
const logger = logger_1.Logger.getInstance("installer.service");
async function makeInstaller(_options) {
    logger.info('Creating build...');
    if (_options.publishOnly) {
        logger.info('Skipping build phase as per --publish-only option');
    }
    if (_options.skipInstall) {
        logger.info('Skipping component installation as per --skip-install option');
    }
    if (!_options.publishOnly) {
        // Clean dist folder to ensure fresh build
        const distDir = path_1.PathUtils.getDistDir();
        if (await (0, fs_extra_1.pathExists)(distDir)) {
            logger.debug(`Cleaning dist folder: ${distDir}`);
            await (0, fs_extra_1.remove)(distDir);
            logger.info('Dist folder cleaned successfully');
        }
        // 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)
        if (!_options.skipInstall) {
            await components_service_1.default.installComponentsForBuild();
        }
        else {
            logger.debug('Skipping component installation due to --skip-install flag');
        }
        // 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");
        // copy license file to binary directory if it exists
        await license_file_service_1.LicenseFileService.copyLicenseFile();
        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') {
        const macOSInstallerHelper = await import('./macOS.helper.js');
        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') {
        const windowsHelper = await import('./windows.helper.js');
        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}`);
    // Check if components directory exists
    if (!(await (0, fs_extra_1.pathExists)(componentsDir))) {
        logger.warn(`Components directory not found at ${componentsDir}. Skipping component copying. Use --skip-install if this is intentional.`);
        return;
    }
    // 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