/**
 * Copyright (C) 2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the ""License"");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an ""AS IS"" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import * as x509 from '@peculiar/x509';
import os from 'os';
import path from 'path';
import { DataValidationError, SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js';
import * as constants from './constants.js';
import { GrpcProxyTlsEnums } from './enumerations.js';
import { HEDERA_PLATFORM_VERSION } from '../../version.js';
export class Templates {
    static renderNetworkPodName(nodeAlias) {
        return `network-${nodeAlias}-0`;
    }
    static renderNetworkSvcName(nodeAlias) {
        return `network-${nodeAlias}-svc`;
    }
    static nodeAliasFromNetworkSvcName(svcName) {
        return svcName.split('-').slice(1, -1).join('-');
    }
    static renderNetworkHeadlessSvcName(nodeAlias) {
        return `network-${nodeAlias}`;
    }
    static renderGossipPemPrivateKeyFile(nodeAlias) {
        return `${constants.SIGNING_KEY_PREFIX}-private-${nodeAlias}.pem`;
    }
    static renderGossipPemPublicKeyFile(nodeAlias) {
        return `${constants.SIGNING_KEY_PREFIX}-public-${nodeAlias}.pem`;
    }
    static renderTLSPemPrivateKeyFile(nodeAlias) {
        return `hedera-${nodeAlias}.key`;
    }
    static renderTLSPemPublicKeyFile(nodeAlias) {
        return `hedera-${nodeAlias}.crt`;
    }
    static renderNodeFriendlyName(prefix, nodeAlias, suffix = '') {
        const parts = [prefix, nodeAlias];
        if (suffix)
            parts.push(suffix);
        return parts.join('-');
    }
    static extractNodeAliasFromPodName(podName) {
        const parts = podName.split('-');
        if (parts.length !== 3)
            throw new DataValidationError(`pod name is malformed : ${podName}`, 3, parts.length);
        return parts[1].trim();
    }
    static prepareReleasePrefix(tag) {
        if (!tag)
            throw new MissingArgumentError('tag cannot be empty');
        const parsed = tag.split('.');
        if (parsed.length < 3)
            throw new Error(`tag (${tag}) must include major, minor and patch fields (e.g. v0.40.4)`);
        return `${parsed[0]}.${parsed[1]}`;
    }
    /**
     * renders the name to be used to store the new account key as a Kubernetes secret
     * @param accountId
     * @returns the name of the Kubernetes secret to store the account key
     */
    static renderAccountKeySecretName(accountId) {
        return `account-key-${accountId.toString()}`;
    }
    /**
     * renders the label selector to be used to fetch the new account key from the Kubernetes secret
     * @param accountId
     * @returns the label selector of the Kubernetes secret to retrieve the account key   */
    static renderAccountKeySecretLabelSelector(accountId) {
        return `solo.hedera.com/account-id=${accountId.toString()}`;
    }
    /**
     * renders the label object to be used to store the new account key in the Kubernetes secret
     * @param accountId
     * @returns the label object to be used to store the new account key in the Kubernetes secret
     */
    static renderAccountKeySecretLabelObject(accountId) {
        return {
            'solo.hedera.com/account-id': accountId.toString(),
        };
    }
    static renderDistinguishedName(nodeAlias, state = 'TX', locality = 'Richardson', org = 'Hedera', orgUnit = 'Hedera', country = 'US') {
        return new x509.Name(`CN=${nodeAlias},ST=${state},L=${locality},O=${org},OU=${orgUnit},C=${country}`);
    }
    static renderStagingDir(cacheDir, releaseTagOverride) {
        let releaseTag = releaseTagOverride;
        if (!cacheDir) {
            throw new IllegalArgumentError('cacheDir cannot be empty');
        }
        if (!releaseTag) {
            releaseTag = HEDERA_PLATFORM_VERSION;
        }
        const releasePrefix = this.prepareReleasePrefix(releaseTag);
        if (!releasePrefix) {
            throw new IllegalArgumentError('releasePrefix cannot be empty');
        }
        return path.resolve(path.join(cacheDir, releasePrefix, 'staging', releaseTag));
    }
    static installationPath(dep, osPlatform = os.platform(), installationDir = path.join(constants.SOLO_HOME_DIR, 'bin')) {
        switch (dep) {
            case constants.HELM:
                if (osPlatform === constants.OS_WINDOWS) {
                    return path.join(installationDir, `${dep}.exe`);
                }
                return path.join(installationDir, dep);
            default:
                throw new SoloError(`unknown dep: ${dep}`);
        }
    }
    static renderFullyQualifiedNetworkPodName(namespace, nodeAlias) {
        return `${Templates.renderNetworkPodName(nodeAlias)}.${Templates.renderNetworkHeadlessSvcName(nodeAlias)}.${namespace}.svc.cluster.local`;
    }
    static renderFullyQualifiedNetworkSvcName(namespace, nodeAlias) {
        return `${Templates.renderNetworkSvcName(nodeAlias)}.${namespace}.svc.cluster.local`;
    }
    static nodeAliasFromFullyQualifiedNetworkSvcName(svcName) {
        const parts = svcName.split('.');
        return this.nodeAliasFromNetworkSvcName(parts[0]);
    }
    static nodeIdFromNodeAlias(nodeAlias) {
        for (let i = nodeAlias.length - 1; i > 0; i--) {
            // @ts-ignore
            if (isNaN(nodeAlias[i])) {
                return parseInt(nodeAlias.substring(i + 1, nodeAlias.length)) - 1;
            }
        }
        throw new SoloError(`Can't get node id from node ${nodeAlias}`);
    }
    static renderGossipKeySecretName(nodeAlias) {
        return `network-${nodeAlias}-keys-secrets`;
    }
    static renderGossipKeySecretLabelObject(nodeAlias) {
        return { 'solo.hedera.com/node-name': nodeAlias };
    }
    /**
     * Creates the secret name based on the node alias type
     *
     * @param nodeAlias - node alias
     * @param type - whether is for gRPC or gRPC Web ( Haproxy or Envoy )
     *
     * @returns the appropriate secret name
     */
    static renderGrpcTlsCertificatesSecretName(nodeAlias, type) {
        switch (type) {
            //? HAProxy Proxy
            case GrpcProxyTlsEnums.GRPC:
                return `haproxy-proxy-secret-${nodeAlias}`;
            //? Envoy Proxy
            case GrpcProxyTlsEnums.GRPC_WEB:
                return `envoy-proxy-secret-${nodeAlias}`;
        }
    }
    /**
     * Creates the secret labels based on the node alias type
     *
     * @param nodeAlias - node alias
     * @param type - whether is for gRPC or gRPC Web ( Haproxy or Envoy )
     *
     * @returns the appropriate secret labels
     */
    static renderGrpcTlsCertificatesSecretLabelObject(nodeAlias, type) {
        switch (type) {
            //? HAProxy Proxy
            case GrpcProxyTlsEnums.GRPC:
                return { 'haproxy-proxy-secret': nodeAlias };
            //? Envoy Proxy
            case GrpcProxyTlsEnums.GRPC_WEB:
                return { 'envoy-proxy-secret': nodeAlias };
        }
    }
    /**
     * Parsed and validates the unparsed value of flag clusterMappings
     *
     * @param unparsed - value of flag clusterMappings
     */
    static parseContextCluster(unparsed) {
        const mapping = {};
        const errorMessage = 'Invalid context in context-cluster, expected structure where context' +
            ' is key = value is cluster and comma delimited if more than one, ' +
            '(e.g.: --context-cluster kind-solo=kind-solo,kind-solo-2=kind-solo-2)';
        unparsed.split(',').forEach(data => {
            const [context, cluster] = data.split('=');
            if (!context || typeof context !== 'string') {
                throw new SoloError(errorMessage, null, { data });
            }
            if (!cluster || typeof cluster !== 'string') {
                throw new SoloError(errorMessage, null, { data });
            }
            mapping[context] = cluster;
        });
        return mapping;
    }
    static renderEnvoyProxyName(nodeAlias) {
        return `envoy-proxy-${nodeAlias}`;
    }
    static renderHaProxyName(nodeAlias) {
        return `haproxy-${nodeAlias}`;
    }
    static renderFullyQualifiedHaProxyName(nodeAlias, namespace) {
        return `${Templates.renderHaProxyName(nodeAlias)}-svc.${namespace}.svc.cluster.local`;
    }
    static parseNodeAliasToIpMapping(unparsed) {
        const mapping = {};
        unparsed.split(',').forEach(data => {
            const [nodeAlias, ip] = data.split('=');
            mapping[nodeAlias] = ip;
        });
        return mapping;
    }
}
//# sourceMappingURL=templates.js.map