"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigManager = void 0;
const fs = __importStar(require("fs"));
const deep_merge_1 = require("../../utils/deep.merge");
const path_1 = require("../../utils/path");
const path_2 = require("path");
const pacakge_json_helper_1 = require("../../utils/pacakge.json.helper");
class ConfigManager {
    static cachedConfig = null;
    static configName = "iocd.cli.config.json";
    static get config() {
        if (!this.cachedConfig) {
            this.cachedConfig = this.loadConfig();
        }
        return this.cachedConfig;
    }
    static getConfigStringWithoutSecrets() {
        const configCopy = JSON.parse(JSON.stringify(ConfigManager.config));
        // Remove or mask any sensitive information here if needed
        if (configCopy.win?.codeSign) {
            configCopy.win.codeSign = "<removed for security>";
        }
        if (configCopy.mac?.codeSign) {
            configCopy.mac.codeSign = "<removed for security>";
        }
        if (configCopy.mac?.notarization) {
            configCopy.mac.notarization = "<removed for security>";
        }
        return JSON.stringify(configCopy, null, 4);
    }
    static saveComponents(newComponents) {
        // read the current config to preserve other fields, do not expand env vars or anything else
        const configPath = path_1.PathUtils.getCliConfigPath();
        const configContent = fs.readFileSync(configPath, 'utf8');
        const currentConfig = JSON.parse(configContent);
        const updatedConfig = {
            ...currentConfig,
            components: {
                ...currentConfig.components,
                list: newComponents
            }
        };
        fs.writeFileSync(configPath, JSON.stringify(updatedConfig, null, 4), 'utf-8');
        // Invalidate cached config, so config is reloaded next time
        this.cachedConfig = null;
    }
    static loadConfig() {
        // Register some env variables that we can use in the config file
        process.env["IOCD_COMPONENT_DIR"] = path_1.PathUtils.getComponentDir("iocd");
        if (!process.env["npm_package_version"]) {
            process.env["npm_package_version"] = pacakge_json_helper_1.PackageJSONHelper.getPackageJson()?.version;
        }
        const defaultConfig = this.getDefaultConfig();
        // Look for iocd.cli.config.json in the config directory
        const configPath = path_1.PathUtils.getCliConfigPath();
        if (!fs.existsSync(configPath)) {
            console.debug(`${this.configName} not found at ${configPath}, using fallback configuration`);
            return this.getDefaultConfig();
        }
        const configContent = fs.readFileSync(configPath, 'utf8');
        // Expand environment variables and template variables in the string before parsing
        const expandedContent = this.expandVariablesInString(configContent);
        const rawConfig = JSON.parse(expandedContent);
        // deep merge with default config to ensure all fields are present
        const final = (0, deep_merge_1.deepMerge)(defaultConfig, rawConfig);
        return final;
    }
    static expandVariablesInString(content) {
        // Expand environment variables in ${VAR_NAME} format
        let expanded = content.replace(/\$\{([^}]+)\}/g, (_, varName) => {
            const value = process.env[varName] || '';
            // Normalize path separators to forward slashes for JSON safety
            return value.replace(/\\/g, '/');
        });
        return expanded;
    }
    static getDefaultConfig() {
        return {
            productSlug: process.env["PRODUCT_SLUG"] || "io.Connect Desktop",
            productName: process.env["PRODUCT_NAME"] || "io.Connect Desktop",
            productDescription: process.env["PRODUCT_DESCRIPTION"] || "io.Connect Desktop is a real-time user interface integration platform.",
            company: process.env["COMPANY"] || "interop.io",
            version: process.env["npm_package_version"] || "1.0.0",
            copyright: process.env["COPYRIGHT"] || "Copyright © 2025 interop.io",
            win: {
                exe: {
                    exeName: process.env["WIN_EXE_NAME"] || "io-connect-desktop.exe",
                    exeIconPath: process.env["WIN_EXE_ICON_PATH"] || (0, path_2.join)(process.env["IOCD_COMPONENT_DIR"] ?? "", "assets/images/logo.ico"),
                }, codeSign: {
                    type: process.env["WIN_CODE_SIGN_TYPE"] || 'off',
                    ...(process.env["WIN_PFX_PATH"] && { pfxPath: process.env["WIN_PFX_PATH"] }),
                    ...(process.env["WIN_PFX_PASS"] && { pfxPassword: process.env["WIN_PFX_PASS"] }),
                    ...(process.env["WIN_CERT_SHA1"] && { certificateSha1: process.env["WIN_CERT_SHA1"] }),
                    ...(process.env["WIN_CUSTOM_CODE_SIGNING"] && { customCodeSignScriptPath: process.env["WIN_CUSTOM_CODE_SIGNING"] }),
                    tsaURL: process.env["WIN_TSA_URL"] || "http://timestamp.digicert.com",
                }
            },
            components: {
                store: {
                    // Set github as default if COMPONENT_STORE is not specified or is "github"
                    ...(!process.env["COMPONENT_STORE"] || process.env["COMPONENT_STORE"] === "github" ? {
                        github: {
                            repo: process.env["COMPONENT_STORE_GITHUB_REPO"] || "interopio/desktop-releases/releases",
                        }
                    } : {}),
                    // Set local if COMPONENT_STORE is "local"
                    ...(process.env["COMPONENT_STORE"] === "local" ? {
                        local: {
                            path: process.env["COMPONENT_STORE_LOCAL_PATH"] || "/components-store"
                        }
                    } : {}),
                    // Set s3 if COMPONENT_STORE is "s3"
                    ...(process.env["COMPONENT_STORE"] === "s3" ? {
                        s3: {
                            bucketName: process.env["COMPONENT_STORE_S3_BUCKET"] || "",
                            region: process.env["COMPONENT_STORE_S3_REGION"] || "us-east-1",
                            ...(process.env["COMPONENT_STORE_S3_PREFIX"] && { prefix: process.env["COMPONENT_STORE_S3_PREFIX"] }),
                            ...(process.env["AWS_ACCESS_KEY_ID"] && { accessKeyId: process.env["AWS_ACCESS_KEY_ID"] }),
                            ...(process.env["AWS_SECRET_ACCESS_KEY"] && { secretAccessKey: process.env["AWS_SECRET_ACCESS_KEY"] })
                        }
                    } : {})
                },
                list: { "iocd": "latest" }
            },
            mac: {
                appBundleName: process.env["MAC_APP_BUNDLE_NAME"] || "io.Connect Desktop.app",
                appBundleId: process.env["MAC_APP_BUNDLE_ID"] || "io.interopio.desktop",
                codeSign: {
                    type: process.env["MAC_CODE_SIGN_TYPE"] || 'keychain',
                    ...(process.env["MAC_IDENTITY"] && { identity: process.env["MAC_IDENTITY"] }),
                    ...(process.env["MAC_KEYCHAIN"] && { keychain: process.env["MAC_KEYCHAIN"] }),
                    ...(process.env["MAC_CERTIFICATE_PATH"] && { certificatePath: process.env["MAC_CERTIFICATE_PATH"] }),
                    ...(process.env["MAC_CERTIFICATE_PASSWORD"] && { certificatePassword: process.env["MAC_CERTIFICATE_PASSWORD"] }),
                    ...(process.env["MAC_CUSTOM_CODE_SIGNING"] && { customCodeSignScriptPath: process.env["MAC_CUSTOM_CODE_SIGNING"] })
                },
                notarization: {
                    type: process.env["MAC_NOTARIZATION_TYPE"] || 'notarytool',
                    appleId: process.env["MAC_NOTARIZATION_APPLE_ID"] || "",
                    appleIdPassword: process.env["MAC_NOTARIZATION_APPLE_ID_PASSWORD"] || "",
                    appleTeamId: process.env["MAC_NOTARIZATION_APPLE_TEAM_ID"] || "",
                    ...(process.env["MAC_CUSTOM_NOTARIZATION"] && { customNotarizationScriptPath: process.env["MAC_CUSTOM_NOTARIZATION"] })
                }
            },
            sentry: process.env["SENTRY_ENABLED"] !== 'false' // default to true
        };
    }
}
exports.ConfigManager = ConfigManager;
//# sourceMappingURL=config.service.js.map