// SPDX-License-Identifier: Apache-2.0
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { Templates } from '../../core/templates.js';
import * as constants from '../../core/constants.js';
import { PrivateKey } from '@hiero-ledger/sdk';
import { SoloError } from '../../core/errors/solo-error.js';
import * as helpers from '../../core/helpers.js';
import { checkNamespace } from '../../core/helpers.js';
import fs from 'node:fs';
import { resolveNamespaceFromDeployment } from '../../core/resolvers.js';
import { Flags as flags } from '../flags.js';
import { inject, injectable } from 'tsyringe-neo';
import { InjectTokens } from '../../core/dependency-injection/inject-tokens.js';
import { patchInject } from '../../core/dependency-injection/container-helper.js';
import { PathEx } from '../../business/utils/path-ex.js';
import { Version } from '../../business/utils/version.js';
import { eq, SemVer } from 'semver';
import { SOLO_USER_AGENT_HEADER } from '../../core/constants.js';
const PREPARE_UPGRADE_CONFIGS_NAME = 'prepareUpgradeConfig';
const ADD_CONFIGS_NAME = 'addConfigs';
const DESTROY_CONFIGS_NAME = 'destroyConfigs';
const UPDATE_CONFIGS_NAME = 'updateConfigs';
const UPGRADE_CONFIGS_NAME = 'upgradeConfigs';
const REFRESH_CONFIGS_NAME = 'refreshConfigs';
const KEYS_CONFIGS_NAME = 'keyConfigs';
const SETUP_CONFIGS_NAME = 'setupConfigs';
const START_CONFIGS_NAME = 'startConfigs';
let NodeCommandConfigs = class NodeCommandConfigs {
    configManager;
    localConfig;
    remoteConfig;
    k8Factory;
    accountManager;
    constructor(configManager, localConfig, remoteConfig, k8Factory, accountManager) {
        this.configManager = configManager;
        this.localConfig = localConfig;
        this.remoteConfig = remoteConfig;
        this.k8Factory = k8Factory;
        this.accountManager = accountManager;
        this.configManager = patchInject(configManager, InjectTokens.ConfigManager, this.constructor.name);
        this.localConfig = patchInject(localConfig, InjectTokens.LocalConfigRuntimeState, this.constructor.name);
        this.k8Factory = patchInject(k8Factory, InjectTokens.K8Factory, this.constructor.name);
        this.accountManager = patchInject(accountManager, InjectTokens.AccountManager, this.constructor.name);
        this.remoteConfig = patchInject(remoteConfig, InjectTokens.RemoteConfigRuntimeState, this.constructor.name);
    }
    async initializeSetup(config, k8Factory) {
        // compute other config parameters
        config.keysDir = PathEx.join(config.cacheDir, 'keys');
        config.stagingDir = Templates.renderStagingDir(config.cacheDir, config.releaseTag);
        config.stagingKeysDir = PathEx.join(config.stagingDir, 'keys');
        if (!(await k8Factory.default().namespaces().has(config.namespace))) {
            throw new SoloError(`namespace ${config.namespace} does not exist`);
        }
        // prepare staging keys directory
        if (!fs.existsSync(config.stagingKeysDir)) {
            fs.mkdirSync(config.stagingKeysDir, { recursive: true });
        }
        // create cached keys dir if it does not exist yet
        if (!fs.existsSync(config.keysDir)) {
            fs.mkdirSync(config.keysDir);
        }
    }
    async prepareUpgradeConfigBuilder(argv, context_, task) {
        context_.config = this.configManager.getConfig(PREPARE_UPGRADE_CONFIGS_NAME, argv.flags, [
            'nodeClient',
            'freezeAdminPrivateKey',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        await this.initializeSetup(context_.config, this.k8Factory);
        context_.config.nodeClient = await this.accountManager.refreshNodeClient(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.skipNodeAlias, context_.config.deployment);
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        return context_.config;
    }
    async upgradeConfigBuilder(argv, context_, task, shouldLoadNodeClient = true) {
        context_.config = this.configManager.getConfig(UPGRADE_CONFIGS_NAME, argv.flags, [
            'allNodeAliases',
            'existingNodeAliases',
            'keysDir',
            'nodeClient',
            'podRefs',
            'stagingDir',
            'stagingKeysDir',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.curDate = new Date();
        context_.config.existingNodeAliases = [];
        context_.config.nodeAliases = helpers.parseNodeAliases(context_.config.nodeAliasesUnparsed, this.remoteConfig.getConsensusNodes(), this.configManager);
        // check if the intended package version exists
        if (context_.config.upgradeVersion) {
            const semVersion = new SemVer(context_.config.upgradeVersion);
            const HEDERA_BUILDS_URL = 'https://builds.hedera.com';
            const BUILD_ZIP_URL = `${HEDERA_BUILDS_URL}/node/software/v${semVersion.major}.${semVersion.minor}/build-${context_.config.upgradeVersion}.zip`;
            try {
                // do not fetch or download, just check if URL exists or not
                const response = await fetch(BUILD_ZIP_URL, {
                    method: 'HEAD',
                    headers: {
                        'User-Agent': SOLO_USER_AGENT_HEADER,
                    },
                });
                if (!response.ok) {
                    throw new SoloError(`Upgrade version ${context_.config.upgradeVersion} does not exist.`);
                }
            }
            catch (error) {
                throw new SoloError(`Failed to fetch upgrade version ${context_.config.upgradeVersion}: ${error.message}`);
            }
        }
        await this.initializeSetup(context_.config, this.k8Factory);
        if (shouldLoadNodeClient) {
            context_.config.nodeClient = await this.accountManager.loadNodeClient(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.deployment);
        }
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        return context_.config;
    }
    async updateConfigBuilder(argv, context_, task, shouldLoadNodeClient = true) {
        context_.config = this.configManager.getConfig(UPDATE_CONFIGS_NAME, argv.flags, [
            'allNodeAliases',
            'existingNodeAliases',
            'freezeAdminPrivateKey',
            'keysDir',
            'nodeClient',
            'podRefs',
            'serviceMap',
            'stagingDir',
            'stagingKeysDir',
            'treasuryKey',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.curDate = new Date();
        context_.config.existingNodeAliases = [];
        await this.initializeSetup(context_.config, this.k8Factory);
        if (shouldLoadNodeClient) {
            context_.config.nodeClient = await this.accountManager.loadNodeClient(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.deployment);
        }
        // check consensus releaseTag to make sure it is a valid semantic version string starting with 'v'
        context_.config.releaseTag = Version.getValidSemanticVersion(context_.config.releaseTag, true, 'Consensus release tag');
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(context_.config.namespace, context_.config.deployment);
        const treasuryAccountPrivateKey = treasuryAccount.privateKey;
        context_.config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey);
        if (context_.config.domainNames) {
            context_.config.domainNamesMapping = Templates.parseNodeAliasToDomainNameMapping(context_.config.domainNames);
        }
        return context_.config;
    }
    async destroyConfigBuilder(argv, context_, task, shouldLoadNodeClient = true) {
        context_.config = this.configManager.getConfig(DESTROY_CONFIGS_NAME, argv.flags, [
            'adminKey',
            'allNodeAliases',
            'existingNodeAliases',
            'freezeAdminPrivateKey',
            'keysDir',
            'nodeClient',
            'podRefs',
            'serviceMap',
            'stagingDir',
            'stagingKeysDir',
            'treasuryKey',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.curDate = new Date();
        context_.config.existingNodeAliases = [];
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        await this.initializeSetup(context_.config, this.k8Factory);
        if (shouldLoadNodeClient) {
            context_.config.nodeClient = await this.accountManager.loadNodeClient(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.deployment);
        }
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(context_.config.namespace, context_.config.deployment);
        const treasuryAccountPrivateKey = treasuryAccount.privateKey;
        context_.config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey);
        if (context_.config.domainNames) {
            context_.config.domainNamesMapping = Templates.parseNodeAliasToDomainNameMapping(context_.config.domainNames);
        }
        return context_.config;
    }
    async addConfigBuilder(argv, context_, task, shouldLoadNodeClient = true) {
        context_.config = this.configManager.getConfig(ADD_CONFIGS_NAME, argv.flags, [
            'allNodeAliases',
            'newNodeAliases',
            'curDate',
            'existingNodeAliases',
            'freezeAdminPrivateKey',
            'keysDir',
            'lastStateZipPath',
            'nodeClient',
            'podRefs',
            'serviceMap',
            'stagingDir',
            'stagingKeysDir',
            'treasuryKey',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.adminKey = argv[flags.adminKey?.name]
            ? PrivateKey.fromStringED25519(argv[flags.adminKey?.name])
            : PrivateKey.fromStringED25519(constants.GENESIS_KEY);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.curDate = new Date();
        context_.config.existingNodeAliases = [];
        await this.initializeSetup(context_.config, this.k8Factory);
        if (shouldLoadNodeClient) {
            context_.config.nodeClient = await this.accountManager.loadNodeClient(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.deployment);
        }
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        const treasuryAccount = await this.accountManager.getTreasuryAccountKeys(context_.config.namespace, context_.config.deployment);
        const treasuryAccountPrivateKey = treasuryAccount.privateKey;
        context_.config.treasuryKey = PrivateKey.fromStringED25519(treasuryAccountPrivateKey);
        context_.config.serviceMap = await this.accountManager.getNodeServiceMap(context_.config.namespace, this.remoteConfig.getClusterRefs(), context_.config.deployment);
        context_.config.consensusNodes = this.remoteConfig.getConsensusNodes();
        context_.config.contexts = this.remoteConfig.getContexts();
        if (!context_.config.clusterRef) {
            context_.config.clusterRef = this.remoteConfig.getClusterRefs()?.entries()?.next()?.value[0];
            if (!context_.config.clusterRef) {
                throw new SoloError('Error during initialization, cluster ref could not be determined');
            }
        }
        if (context_.config.domainNames) {
            context_.config.domainNamesMapping = Templates.parseNodeAliasToDomainNameMapping(context_.config.domainNames);
        }
        return context_.config;
    }
    async logsConfigBuilder(_argv, context_, task) {
        context_.config = {
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed), this.remoteConfig.getConsensusNodes(), this.configManager),
            nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed),
            deployment: this.configManager.getFlag(flags.deployment),
            consensusNodes: this.remoteConfig.getConsensusNodes(),
            contexts: this.remoteConfig.getContexts(),
        };
        return context_.config;
    }
    async connectionsConfigBuilder(_argv, context_, task) {
        context_.config = {
            deployment: this.configManager.getFlag(flags.deployment),
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            contexts: this.remoteConfig.getContexts()[0],
        };
        return context_.config;
    }
    async statesConfigBuilder(_argv, context_, task) {
        const consensusNodes = this.remoteConfig.getConsensusNodes();
        context_.config = {
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed), consensusNodes, this.configManager),
            nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed),
            deployment: this.configManager.getFlag(flags.deployment),
            consensusNodes,
            contexts: this.remoteConfig.getContexts(),
        };
        return context_.config;
    }
    async refreshConfigBuilder(argv, context_, task) {
        context_.config = this.configManager.getConfig(REFRESH_CONFIGS_NAME, argv.flags, [
            'nodeAliases',
            'podRefs',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.nodeAliases = helpers.parseNodeAliases(context_.config.nodeAliasesUnparsed, this.remoteConfig.getConsensusNodes(), this.configManager);
        await this.initializeSetup(context_.config, this.k8Factory);
        if (context_.config.domainNames) {
            context_.config.domainNamesMapping = Templates.parseNodeAliasToDomainNameMapping(context_.config.domainNames);
        }
        return context_.config;
    }
    async keysConfigBuilder(argv, context_) {
        context_.config = this.configManager.getConfig(KEYS_CONFIGS_NAME, argv.flags, [
            'curDate',
            'keysDir',
            'nodeAliases',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.curDate = new Date();
        context_.config.nodeAliases = helpers.parseNodeAliases(context_.config.nodeAliasesUnparsed, this.remoteConfig.getConsensusNodes(), this.configManager);
        context_.config.keysDir = PathEx.join(this.configManager.getFlag(flags.cacheDir), 'keys');
        if (!fs.existsSync(context_.config.keysDir)) {
            fs.mkdirSync(context_.config.keysDir);
        }
        return context_.config;
    }
    async stopConfigBuilder(_argv, context_, task) {
        const consensusNodes = this.remoteConfig.getConsensusNodes();
        context_.config = {
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            nodeAliases: helpers.parseNodeAliases(this.configManager.getFlag(flags.nodeAliasesUnparsed), consensusNodes, this.configManager),
            nodeAliasesUnparsed: this.configManager.getFlag(flags.nodeAliasesUnparsed),
            deployment: this.configManager.getFlag(flags.deployment),
            consensusNodes,
            contexts: this.remoteConfig.getContexts(),
        };
        await checkNamespace(context_.config.consensusNodes, this.k8Factory, context_.config.namespace);
        return context_.config;
    }
    async freezeConfigBuilder(_argv, context_, task) {
        context_.config = {
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            deployment: this.configManager.getFlag(flags.deployment),
            consensusNodes: this.remoteConfig.getConsensusNodes(),
            contexts: this.remoteConfig.getContexts(),
        };
        await checkNamespace(context_.config.consensusNodes, this.k8Factory, context_.config.namespace);
        const freezeAdminAccountId = this.accountManager.getFreezeAccountId(context_.config.deployment);
        const accountKeys = await this.accountManager.getAccountKeysFromSecret(freezeAdminAccountId.toString(), context_.config.namespace);
        context_.config.freezeAdminPrivateKey = accountKeys.privateKey;
        return context_.config;
    }
    async startConfigBuilder(argv, context_, task) {
        context_.config = this.configManager.getConfig(START_CONFIGS_NAME, argv.flags, [
            'nodeAliases',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.consensusNodes = this.remoteConfig.getConsensusNodes();
        for (const consensusNode of context_.config.consensusNodes) {
            const k8 = this.k8Factory.getK8(consensusNode.context);
            if (!(await k8.namespaces().has(context_.config.namespace))) {
                throw new SoloError(`namespace ${context_.config.namespace} does not exist`);
            }
        }
        context_.config.nodeAliases = helpers.parseNodeAliases(context_.config.nodeAliasesUnparsed, context_.config.consensusNodes, this.configManager);
        return context_.config;
    }
    async restartConfigBuilder(_argv, context_, task) {
        context_.config = {
            namespace: await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task),
            deployment: this.configManager.getFlag(flags.deployment),
            consensusNodes: this.remoteConfig.getConsensusNodes(),
            contexts: this.remoteConfig.getContexts(),
        };
        await checkNamespace(context_.config.consensusNodes, this.k8Factory, context_.config.namespace);
        return context_.config;
    }
    async setupConfigBuilder(argv, context_, task) {
        context_.config = this.configManager.getConfig(SETUP_CONFIGS_NAME, argv.flags, [
            'nodeAliases',
            'podRefs',
            'namespace',
            'consensusNodes',
            'contexts',
        ]);
        const savedVersion = this.remoteConfig.configuration.versions.consensusNode;
        if (!eq(savedVersion, new SemVer(context_.config.releaseTag)) && // allow different versions only for local builds
            !context_.config.localBuildPath) {
            throw new SoloError(`Consensus node version saved in remote config ${savedVersion} is different from ${context_.config.releaseTag}`);
        }
        context_.config.namespace = await resolveNamespaceFromDeployment(this.localConfig, this.configManager, task);
        context_.config.consensusNodes = this.remoteConfig.getConsensusNodes();
        context_.config.nodeAliases = helpers.parseNodeAliases(context_.config.nodeAliasesUnparsed, context_.config.consensusNodes, this.configManager);
        await this.initializeSetup(context_.config, this.k8Factory);
        if (context_.config.domainNames) {
            context_.config.domainNamesMapping = Templates.parseNodeAliasToDomainNameMapping(context_.config.domainNames);
        }
        return context_.config;
    }
};
NodeCommandConfigs = __decorate([
    injectable(),
    __param(0, inject(InjectTokens.ConfigManager)),
    __param(1, inject(InjectTokens.LocalConfigRuntimeState)),
    __param(2, inject(InjectTokens.RemoteConfigRuntimeState)),
    __param(3, inject(InjectTokens.K8Factory)),
    __param(4, inject(InjectTokens.AccountManager)),
    __metadata("design:paramtypes", [Function, Function, Object, Object, Function])
], NodeCommandConfigs);
export { NodeCommandConfigs };
//# sourceMappingURL=configs.js.map