// SPDX-License-Identifier: Apache-2.0
import { main } from '../../../../src/index.js';
import { Flags } from '../../../../src/commands/flags.js';
import { Duration } from '../../../../src/core/time/duration.js';
import { BaseCommandTest } from './base-command-test.js';
import { BlockCommandDefinition } from '../../../../src/commands/command-definitions/block-command-definition.js';
import * as constants from '../../../../src/core/constants.js';
import { expect } from 'chai';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import { HEDERA_HAPI_PATH } from '../../../../src/core/constants.js';
import { K8Helper } from '../../../../src/business/utils/k8-helper.js';
export class BlockNodeTest extends BaseCommandTest {
    static soloBlockNodeDeployArgv(testName, deployment, clusterReference, enableLocalBuildPathTesting, localBuildReleaseTag, nodeAliases) {
        const { newArgv, argvPushGlobalFlags, optionFromFlag } = BlockNodeTest;
        const argv = newArgv();
        argv.push(BlockCommandDefinition.COMMAND_NAME, BlockCommandDefinition.NODE_SUBCOMMAND_NAME, BlockCommandDefinition.NODE_ADD, optionFromFlag(Flags.deployment), deployment, optionFromFlag(Flags.clusterRef), clusterReference);
        if (enableLocalBuildPathTesting) {
            argv.push(optionFromFlag(Flags.releaseTag), localBuildReleaseTag);
        }
        if (nodeAliases !== undefined && nodeAliases.length > 0) {
            const stringBuilder = [];
            for (const nodeAlias of nodeAliases) {
                stringBuilder.push(`${nodeAlias}=1`);
            }
            argv.push(optionFromFlag(Flags.priorityMapping), stringBuilder.join(','));
        }
        argvPushGlobalFlags(argv, testName, false, true);
        return argv;
    }
    static soloBlockNodeAddExternalArgv(testName, deployment, clusterReference, address, nodeAliases) {
        const { newArgv, argvPushGlobalFlags, optionFromFlag } = BlockNodeTest;
        const argv = newArgv();
        argv.push(BlockCommandDefinition.COMMAND_NAME, BlockCommandDefinition.NODE_SUBCOMMAND_NAME, BlockCommandDefinition.NODE_ADD_EXTERNAL, optionFromFlag(Flags.deployment), deployment, optionFromFlag(Flags.clusterRef), clusterReference, optionFromFlag(Flags.externalBlockNodeAddress), address);
        if (nodeAliases !== undefined && nodeAliases.length > 0) {
            const stringBuilder = [];
            for (const nodeAlias of nodeAliases) {
                stringBuilder.push(`${nodeAlias}=1`);
            }
            argv.push(optionFromFlag(Flags.priorityMapping), stringBuilder.join(','));
        }
        argvPushGlobalFlags(argv, testName, false, true);
        return argv;
    }
    static soloBlockNodeDestroyArgv(testName, deployment, clusterReference) {
        const { newArgv, argvPushGlobalFlags, optionFromFlag } = BlockNodeTest;
        const argv = newArgv();
        argv.push(BlockCommandDefinition.COMMAND_NAME, BlockCommandDefinition.NODE_SUBCOMMAND_NAME, BlockCommandDefinition.NODE_DESTROY, optionFromFlag(Flags.deployment), deployment, optionFromFlag(Flags.clusterRef), clusterReference, optionFromFlag(Flags.force), optionFromFlag(Flags.quiet), optionFromFlag(Flags.devMode));
        argvPushGlobalFlags(argv, testName, false, true);
        return argv;
    }
    static soloBlockNodeDeleteExternalArgv(testName, deployment, clusterReference, id) {
        const { newArgv, argvPushGlobalFlags, optionFromFlag } = BlockNodeTest;
        const argv = newArgv();
        argv.push(BlockCommandDefinition.COMMAND_NAME, BlockCommandDefinition.NODE_SUBCOMMAND_NAME, BlockCommandDefinition.NODE_DELETE_EXTERNAL, optionFromFlag(Flags.deployment), deployment, optionFromFlag(Flags.clusterRef), clusterReference, optionFromFlag(Flags.force), optionFromFlag(Flags.quiet), optionFromFlag(Flags.devMode));
        if (id !== undefined) {
            argv.push(optionFromFlag(Flags.id), id.toString());
        }
        argvPushGlobalFlags(argv, testName);
        return argv;
    }
    static add(options, nodeAliases) {
        const { testName, deployment, clusterReferenceNameArray, localBuildReleaseTag, enableLocalBuildPathTesting } = options;
        const { soloBlockNodeDeployArgv } = BlockNodeTest;
        it(`${testName}: block node add`, async () => {
            await main(soloBlockNodeDeployArgv(testName, deployment, clusterReferenceNameArray[0], enableLocalBuildPathTesting, localBuildReleaseTag, nodeAliases));
        }).timeout(Duration.ofMinutes(5).toMillis());
    }
    static addExternal(options, address, nodeAliases) {
        const { testName, deployment, clusterReferenceNameArray } = options;
        const { soloBlockNodeAddExternalArgv } = BlockNodeTest;
        it(`${testName}: block node add-external`, async () => {
            await main(soloBlockNodeAddExternalArgv(testName, deployment, clusterReferenceNameArray[0], address, nodeAliases));
        }).timeout(Duration.ofMinutes(5).toMillis());
    }
    static deleteExternal(options, id) {
        const { testName, deployment, clusterReferenceNameArray } = options;
        const { soloBlockNodeDeleteExternalArgv } = BlockNodeTest;
        it(`${testName}: block node delete-external`, async () => {
            await main(soloBlockNodeDeleteExternalArgv(testName, deployment, clusterReferenceNameArray[1], id));
        }).timeout(Duration.ofMinutes(5).toMillis());
    }
    static destroy(options) {
        const { testName, deployment, clusterReferenceNameArray } = options;
        const { soloBlockNodeDestroyArgv } = BlockNodeTest;
        it(`${testName}: block node destroy`, async () => {
            await main(soloBlockNodeDestroyArgv(testName, deployment, clusterReferenceNameArray[1]));
        }).timeout(Duration.ofMinutes(5).toMillis());
    }
    static testBlockNode(options, blockNodeId = 1) {
        const { namespace, contexts, testName } = options;
        const execAsync = promisify(exec);
        it(`${testName}: test block node connection for block node ${blockNodeId}`, async () => {
            const pod = await new K8Helper(contexts[0]).getBlockNodePod(namespace, blockNodeId);
            const srv = await pod.portForward(constants.BLOCK_NODE_PORT, constants.BLOCK_NODE_PORT);
            const commandOptions = { cwd: './test/data', maxBuffer: 50 * 1024 * 1024, encoding: 'utf8' };
            // Make script executable
            await execAsync('chmod +x ./get-block.sh', commandOptions);
            // Execute script
            const scriptStd = await execAsync('./get-block.sh 1', commandOptions);
            expect(scriptStd.stderr).to.equal('');
            expect(scriptStd.stdout).to.include('"status": "SUCCESS"');
            await pod.stopPortForward(srv);
        });
    }
    static verifyBlockNodesJson(options, nodeAlias, blockNodeIds, excludedBlockNodeIds = [], { expectedExternalAddress, expectedExternalPort, unexpectedExternalAddress, unexpectedExternalPort, }) {
        const { namespace, contexts, testName } = options;
        it(`${testName}: verify block-nodes.json for ${nodeAlias}`, async () => {
            const root = await new K8Helper(contexts[0]).getConsensusNodeRootContainer(namespace, nodeAlias);
            const output = await root.execContainer([
                'bash',
                '-c',
                `cat ${HEDERA_HAPI_PATH}/data/config/block-nodes.json`,
            ]);
            for (const blockNodeId of blockNodeIds) {
                expect(output).to.include(`block-node-${blockNodeId}`);
            }
            for (const excludedBlockNodeId of excludedBlockNodeIds) {
                expect(output).to.not.include(`block-node-${excludedBlockNodeId}`);
            }
            if (expectedExternalAddress !== undefined) {
                expect(output).to.include(expectedExternalAddress);
            }
            if (expectedExternalPort !== undefined) {
                expect(output).to.include(expectedExternalPort.toString());
            }
            if (unexpectedExternalAddress !== undefined) {
                expect(output).not.to.include(unexpectedExternalAddress);
            }
            if (unexpectedExternalPort !== undefined) {
                expect(output).not.to.include(unexpectedExternalPort.toString());
            }
        });
    }
}
//# sourceMappingURL=block-node-test.js.map