// SPDX-License-Identifier: Apache-2.0
import fs from 'node:fs';
import * as constants from './constants.js';
import { PathEx } from '../business/utils/path-ex.js';
import yaml from 'yaml';
export class HelmValuesHelper {
    constructor() { }
    buildPerNodeExtraEnvironmentValuesStructure(consensusNodes, options = {}) {
        const hedera = { nodes: [] };
        for (const [nodeIndex, consensusNode] of consensusNodes.entries()) {
            const extraEnvironmentVariables = [
                ...(options.baseExtraEnvironmentVariables?.[consensusNode.name] ?? []),
            ];
            if (options.useJavaMainClass) {
                this.setExtraEnvironmentVariable(extraEnvironmentVariables, 'JAVA_MAIN_CLASS', 'com.swirlds.platform.Browser');
            }
            if (options.wrapsEnabled && options.tss) {
                const wrapPath = `${constants.HEDERA_HAPI_PATH}/${options.tss.wraps.artifactsFolderName}`;
                this.setExtraEnvironmentVariable(extraEnvironmentVariables, 'TSS_LIB_WRAPS_ARTIFACTS_PATH', wrapPath);
            }
            if (options.debugNodeAlias === consensusNode.name) {
                const debugJavaOptions = `-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:${constants.JVM_DEBUG_PORT}`;
                const javaOptionsIndex = extraEnvironmentVariables.findIndex((environmentVariable) => environmentVariable.name === 'JAVA_OPTS');
                if (javaOptionsIndex === -1) {
                    extraEnvironmentVariables.push({
                        name: 'JAVA_OPTS',
                        value: debugJavaOptions,
                    });
                }
                else {
                    extraEnvironmentVariables[javaOptionsIndex].value =
                        `${debugJavaOptions} ${extraEnvironmentVariables[javaOptionsIndex].value}`.trim();
                }
            }
            if (options.additionalEnvironmentVariables && options.additionalEnvironmentVariables[consensusNode.name]) {
                for (const additionalEnvironmentVariable of options.additionalEnvironmentVariables[consensusNode.name]) {
                    this.setExtraEnvironmentVariable(extraEnvironmentVariables, additionalEnvironmentVariable.name, additionalEnvironmentVariable.value);
                }
            }
            const finalJavaOptionsIndex = extraEnvironmentVariables.findIndex((environmentVariable) => environmentVariable.name === 'JAVA_OPTS');
            if (finalJavaOptionsIndex !== -1) {
                extraEnvironmentVariables[finalJavaOptionsIndex].value = this.sanitizeJavaOptionsForHeapSettings(extraEnvironmentVariables[finalJavaOptionsIndex].value);
            }
            while (hedera.nodes.length <= nodeIndex) {
                hedera.nodes.push({});
            }
            const nodeValues = {};
            if (extraEnvironmentVariables.length > 0) {
                nodeValues.root = { extraEnv: extraEnvironmentVariables };
            }
            const additionalNodeValues = options.additionalNodeValues?.[consensusNode.name];
            if (additionalNodeValues?.name) {
                nodeValues.name = additionalNodeValues.name;
            }
            if (typeof additionalNodeValues?.nodeId === 'number') {
                nodeValues.nodeId = additionalNodeValues.nodeId;
            }
            if (additionalNodeValues?.accountId) {
                nodeValues.accountId = additionalNodeValues.accountId;
            }
            if (additionalNodeValues?.blockNodesJson) {
                nodeValues.blockNodesJson = additionalNodeValues.blockNodesJson;
            }
            hedera.nodes[nodeIndex] = nodeValues;
        }
        return { hedera };
    }
    generateExtraEnvironmentValuesFile(consensusNodes, options = {}, cacheDirectory) {
        const perNodeExtraEnvironmentValues = this.buildPerNodeExtraEnvironmentValuesStructure(consensusNodes, options);
        const filename = `per-node-extra-env-${Date.now()}-${Math.random().toString(36).slice(2)}.yaml`;
        const filePath = PathEx.join(cacheDirectory, filename);
        const yamlContent = yaml.stringify(perNodeExtraEnvironmentValues, { indent: 2 });
        fs.writeFileSync(filePath, yamlContent);
        return filePath;
    }
    parseValuesFilePaths(valuesArgument) {
        const filePaths = [];
        const regex = /--values\s+"([^"]+)"|--values\s+(\S+)/g;
        let match;
        while ((match = regex.exec(valuesArgument)) !== null) {
            filePaths.push(match[1] ?? match[2]);
        }
        return filePaths;
    }
    parseValuesFile(filePath) {
        let content;
        try {
            content = fs.readFileSync(filePath, 'utf8');
        }
        catch {
            return undefined;
        }
        let parsedValues;
        try {
            parsedValues = yaml.parse(content);
        }
        catch {
            return undefined;
        }
        if (!parsedValues || typeof parsedValues !== 'object') {
            return undefined;
        }
        return parsedValues;
    }
    readHederaNodes(valuesFilePath) {
        const parsedRecord = this.parseValuesFile(valuesFilePath);
        if (!parsedRecord) {
            return undefined;
        }
        const hederaSection = parsedRecord.hedera;
        if (!hederaSection || typeof hederaSection !== 'object') {
            return undefined;
        }
        const nodesArray = hederaSection.nodes;
        if (!Array.isArray(nodesArray)) {
            return undefined;
        }
        return nodesArray;
    }
    extractExtraEnvironmentFromValuesFiles(filePaths, consensusNodes) {
        const result = {};
        for (const filePath of filePaths) {
            const parsedRecord = this.parseValuesFile(filePath);
            if (!parsedRecord) {
                continue;
            }
            const defaultsSection = parsedRecord.defaults;
            if (defaultsSection && typeof defaultsSection === 'object') {
                const defaultsRootSection = defaultsSection.root;
                const defaultsEnvironmentVariables = this.extractExtraEnvironmentArray(defaultsRootSection);
                if (defaultsEnvironmentVariables.length > 0) {
                    for (const consensusNode of consensusNodes) {
                        this.mergeIntoResult(result, consensusNode.name, defaultsEnvironmentVariables);
                    }
                }
            }
            const hederaSection = parsedRecord.hedera;
            if (!hederaSection || typeof hederaSection !== 'object') {
                continue;
            }
            const nodesArray = hederaSection.nodes;
            if (!Array.isArray(nodesArray)) {
                continue;
            }
            for (const [helmNodeIndex, consensusNode] of consensusNodes.entries()) {
                const nodeEntry = nodesArray[helmNodeIndex];
                if (!nodeEntry || typeof nodeEntry !== 'object') {
                    continue;
                }
                const nodeRootSection = nodeEntry.root;
                const nodeEnvironmentVariables = this.extractExtraEnvironmentArray(nodeRootSection);
                if (nodeEnvironmentVariables.length > 0) {
                    this.mergeIntoResult(result, consensusNode.name, nodeEnvironmentVariables);
                }
            }
        }
        return result;
    }
    extractPerNodeBlockNodesJsonFromValuesFile(valuesFilePath, consensusNodes) {
        const result = {};
        const nodesArray = this.readHederaNodes(valuesFilePath);
        if (!nodesArray) {
            return result;
        }
        for (const [helmNodeIndex, consensusNode] of consensusNodes.entries()) {
            const nodeEntry = nodesArray[helmNodeIndex];
            if (!nodeEntry || typeof nodeEntry !== 'object') {
                continue;
            }
            const blockNodesJson = nodeEntry.blockNodesJson;
            if (typeof blockNodesJson === 'string') {
                result[consensusNode.name] = blockNodesJson;
            }
        }
        return result;
    }
    extractPerNodeIdentityFromValuesFile(valuesFilePath, consensusNodes) {
        const result = {};
        const nodesArray = this.readHederaNodes(valuesFilePath);
        if (!nodesArray) {
            return result;
        }
        for (const [helmNodeIndex, consensusNode] of consensusNodes.entries()) {
            const nodeEntry = nodesArray[helmNodeIndex];
            if (!nodeEntry || typeof nodeEntry !== 'object') {
                continue;
            }
            const entry = nodeEntry;
            const identity = {};
            if (typeof entry.name === 'string') {
                identity.name = entry.name;
            }
            if (typeof entry.nodeId === 'number') {
                identity.nodeId = entry.nodeId;
            }
            else if (typeof entry.nodeId === 'string') {
                const parsed = Number.parseInt(entry.nodeId, 10);
                if (!Number.isNaN(parsed)) {
                    identity.nodeId = parsed;
                }
            }
            if (typeof entry.accountId === 'string') {
                identity.accountId = entry.accountId;
            }
            result[consensusNode.name] = identity;
        }
        return result;
    }
    sanitizeJavaOptionsForHeapSettings(javaOptions) {
        return javaOptions
            .replaceAll(/(^|\s)-Xms\s*\S+/g, '$1')
            .replaceAll(/(^|\s)-Xmx\s*\S+/g, '$1')
            .replaceAll(/\s+/g, ' ')
            .trim();
    }
    setExtraEnvironmentVariable(extraEnvironmentVariables, name, value) {
        const environmentVariableIndex = extraEnvironmentVariables.findIndex((environmentVariable) => environmentVariable.name === name);
        if (environmentVariableIndex === -1) {
            extraEnvironmentVariables.push({ name, value });
        }
        else {
            extraEnvironmentVariables[environmentVariableIndex].value = value;
        }
    }
    mergeIntoResult(result, nodeAlias, environmentVariables) {
        if (!result[nodeAlias]) {
            result[nodeAlias] = [];
        }
        for (const environmentVariable of environmentVariables) {
            const existingIndex = result[nodeAlias].findIndex((variable) => variable.name === environmentVariable.name);
            const environmentVariableClone = { ...environmentVariable };
            if (existingIndex === -1) {
                result[nodeAlias].push(environmentVariableClone);
            }
            else {
                result[nodeAlias][existingIndex] = environmentVariableClone;
            }
        }
    }
    extractExtraEnvironmentArray(rootSection) {
        if (!rootSection || typeof rootSection !== 'object') {
            return [];
        }
        const extraEnvironmentArray = rootSection.extraEnv;
        if (!Array.isArray(extraEnvironmentArray)) {
            return [];
        }
        const environmentVariables = [];
        for (const entry of extraEnvironmentArray) {
            if (!entry || typeof entry !== 'object') {
                continue;
            }
            const entryRecord = entry;
            if (typeof entryRecord.name !== 'string' || typeof entryRecord.value !== 'string') {
                continue;
            }
            environmentVariables.push({ name: entryRecord.name, value: entryRecord.value });
        }
        return environmentVariables;
    }
}
export const helmValuesHelper = new HelmValuesHelper();
//# sourceMappingURL=helm-values-helper.js.map