// 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 { HEDERA_HAPI_PATH, ROOT_CONTAINER, SOLO_LOGS_DIR } from './constants.js';
import fs from 'node:fs';
import { ContainerReference } from '../integration/kube/resources/container/container-reference.js';
import * as constants from './constants.js';
import { sleep } from './helpers.js';
import { Duration } from './time/duration.js';
import { inject, injectable } from 'tsyringe-neo';
import { patchInject } from './dependency-injection/container-helper.js';
import { InjectTokens } from './dependency-injection/inject-tokens.js';
import { PathEx } from '../business/utils/path-ex.js';
/**
 * Class to manage network nodes
 */
let NetworkNodes = class NetworkNodes {
    logger;
    k8Factory;
    constructor(logger, k8Factory) {
        this.logger = logger;
        this.k8Factory = k8Factory;
        this.logger = patchInject(logger, InjectTokens.SoloLogger, this.constructor.name);
        this.k8Factory = patchInject(k8Factory, InjectTokens.K8Factory, this.constructor.name);
    }
    /**
     * Download logs files from all network pods and save to local solo log directory
     * @param namespace - the namespace of the network
     * @param [contexts]
     * @returns a promise that resolves when the logs are downloaded
     */
    async getLogs(namespace, contexts) {
        const podsData = [];
        if (contexts) {
            for (const context of contexts) {
                const pods = await this.k8Factory
                    .getK8(context)
                    .pods()
                    .list(namespace, ['solo.hedera.com/type=network-node']);
                for (const pod of pods) {
                    podsData.push({ pod, context });
                }
            }
        }
        else {
            const pods = await this.k8Factory.default().pods().list(namespace, ['solo.hedera.com/type=network-node']);
            for (const pod of pods) {
                podsData.push({ pod });
            }
        }
        const timeString = new Date().toISOString().replaceAll(':', '-').replaceAll('.', '-');
        const promises = [];
        for (const podData of podsData) {
            promises.push(this.getLog(podData.pod, namespace, timeString, podData.context));
        }
        return await Promise.all(promises);
    }
    async getLog(pod, namespace, timeString, context) {
        const podReference = pod.podReference;
        this.logger.debug(`getNodeLogs(${pod.podReference.name.name}): begin...`);
        const targetDirectory = PathEx.join(SOLO_LOGS_DIR, namespace.name, timeString);
        try {
            if (!fs.existsSync(targetDirectory)) {
                fs.mkdirSync(targetDirectory, { recursive: true });
            }
            const containerReference = ContainerReference.of(podReference, ROOT_CONTAINER);
            const scriptName = 'support-zip.sh';
            const sourcePath = PathEx.joinWithRealPath(constants.RESOURCES_DIR, scriptName); // script source path
            const k8 = this.k8Factory.getK8(context);
            const container = k8.containers().readByRef(containerReference);
            await container.copyTo(sourcePath, `${HEDERA_HAPI_PATH}`);
            await sleep(Duration.ofSeconds(3)); // wait for the script to sync to the file system
            await k8
                .containers()
                .readByRef(containerReference)
                .execContainer([
                'bash',
                '-c',
                `sync ${HEDERA_HAPI_PATH} && sudo chown hedera:hedera ${HEDERA_HAPI_PATH}/${scriptName}`,
            ]);
            await k8
                .containers()
                .readByRef(containerReference)
                .execContainer(['bash', '-c', `sudo chmod 0755 ${HEDERA_HAPI_PATH}/${scriptName}`]);
            await k8.containers().readByRef(containerReference).execContainer(`${HEDERA_HAPI_PATH}/${scriptName}`);
            await k8
                .containers()
                .readByRef(containerReference)
                .copyFrom(`${HEDERA_HAPI_PATH}/data/${podReference.name}.zip`, targetDirectory);
        }
        catch (error) {
            // not throw error here, so we can continue to finish downloading logs from other pods
            // and also delete namespace in the end
            this.logger.error(`${constants.NODE_LOG_FAILURE_MSG} ${podReference}`, error);
        }
        this.logger.debug(`getNodeLogs(${pod.podReference.name.name}): ...end`);
    }
    /**
     * Download state files from a pod
     * @param namespace - the namespace of the network
     * @param nodeAlias - the pod name
     * @param [context]
     * @returns a promise that resolves when the state files are downloaded
     */
    async getStatesFromPod(namespace, nodeAlias, context) {
        const pods = await this.k8Factory
            .getK8(context)
            .pods()
            .list(namespace, [`solo.hedera.com/node-name=${nodeAlias}`, 'solo.hedera.com/type=network-node']);
        // get length of pods
        const promises = [];
        for (const pod of pods) {
            promises.push(this.getState(pod, namespace, context));
        }
        return await Promise.all(promises);
    }
    async getState(pod, namespace, context) {
        const podReference = pod.podReference;
        this.logger.debug(`getNodeState(${pod.podReference.name.name}): begin...`);
        const targetDirectory = PathEx.join(SOLO_LOGS_DIR, namespace.name);
        try {
            if (!fs.existsSync(targetDirectory)) {
                fs.mkdirSync(targetDirectory, { recursive: true });
            }
            const zipCommand = `tar -czf ${HEDERA_HAPI_PATH}/${podReference.name}-state.zip -C ${HEDERA_HAPI_PATH}/data/saved .`;
            const containerReference = ContainerReference.of(podReference, ROOT_CONTAINER);
            const k8 = this.k8Factory.getK8(context);
            await k8.containers().readByRef(containerReference).execContainer(zipCommand);
            await k8
                .containers()
                .readByRef(containerReference)
                .copyFrom(`${HEDERA_HAPI_PATH}/${podReference.name}-state.zip`, targetDirectory);
        }
        catch (error) {
            this.logger.error(`failed to download state from pod ${podReference.name}`, error);
            this.logger.showUser(`Failed to download state from pod ${podReference.name}` + error);
        }
        this.logger.debug(`getNodeState(${pod.podReference.name.name}): ...end`);
    }
    async getNetworkNodePodStatus(podReference, context) {
        return this.k8Factory
            .getK8(context)
            .containers()
            .readByRef(ContainerReference.of(podReference, constants.ROOT_CONTAINER))
            .execContainer([
            'bash',
            '-c',
            String.raw `curl -s http://localhost:9999/metrics | grep platform_PlatformStatus | grep -v \#`,
        ]);
    }
};
NetworkNodes = __decorate([
    injectable(),
    __param(0, inject(InjectTokens.SoloLogger)),
    __param(1, inject(InjectTokens.K8Factory)),
    __metadata("design:paramtypes", [Object, Object])
], NetworkNodes);
export { NetworkNodes };
//# sourceMappingURL=network-nodes.js.map