"use strict";
/*
 * Copyright 2020 NEM
 *
 * 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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.VotingService = void 0;
const path_1 = require("path");
const logger_1 = require("../logger");
const LoggerFactory_1 = require("../logger/LoggerFactory");
const BootstrapUtils_1 = require("./BootstrapUtils");
const logger = LoggerFactory_1.default.getLogger(logger_1.LogType.System);
class VotingService {
    constructor(params) {
        this.params = params;
    }
    async run(presetData, nodeAccount, nodePreset) {
        const symbolServerToolsImage = presetData.symbolServerToolsImage;
        if ((nodePreset === null || nodePreset === void 0 ? void 0 : nodePreset.voting) && nodeAccount.voting) {
            const privateKeyTreeFileName = 'private_key_tree1.dat';
            const target = this.params.target;
            const votingKeysFolder = path_1.join(BootstrapUtils_1.BootstrapUtils.getTargetNodesFolder(target, true, nodeAccount.name), presetData.votingKeysDirectory);
            const metadataFile = path_1.join(votingKeysFolder, 'metadata.yml');
            if (!(await this.shouldGenerateVoting(presetData, metadataFile, nodeAccount.voting))) {
                logger.info(`Voting File for node ${nodePreset.name} has been previously generated. Reusing...`);
                return;
            }
            const votingPrivateKey = nodeAccount === null || nodeAccount === void 0 ? void 0 : nodeAccount.voting.privateKey;
            if (!votingPrivateKey) {
                throw new Error('Voting key should have been previously generated!!! You need to reset your target folder. Please run --reset using your original custom preset.');
            }
            const cmd = [
                `${presetData.catapultAppFolder}/bin/catapult.tools.votingkey`,
                `--secret=${votingPrivateKey}`,
                `--startEpoch=${presetData.votingKeyStartEpoch}`,
                `--endEpoch=${presetData.votingKeyEndEpoch}`,
                `--output=/votingKeys/${privateKeyTreeFileName}`,
            ];
            await BootstrapUtils_1.BootstrapUtils.deleteFolder(votingKeysFolder);
            await BootstrapUtils_1.BootstrapUtils.mkdir(votingKeysFolder);
            const binds = [`${votingKeysFolder}:/votingKeys:rw`];
            const userId = await BootstrapUtils_1.BootstrapUtils.resolveDockerUserFromParam(this.params.user);
            const { stdout, stderr } = await BootstrapUtils_1.BootstrapUtils.runImageUsingExec({
                catapultAppFolder: presetData.catapultAppFolder,
                image: symbolServerToolsImage,
                userId: userId,
                cmds: cmd,
                binds: binds,
            });
            if (stdout.indexOf('<error> ') > -1) {
                logger.info(stdout);
                logger.error(stderr);
                throw new Error('Voting key failed. Check the logs!');
            }
            logger.warn(`A new Voting File for the node ${nodeAccount.name} has been regenerated! `);
            logger.warn(`Remember to send a Voting Key Link transaction from main ${nodeAccount.main.address} using the Voting Public Key ${nodeAccount.voting.publicKey} with startEpoch ${presetData.votingKeyStartEpoch} and endEpoch: ${presetData.votingKeyEndEpoch}`);
            logger.warn('For linking, you can use symbol-bootstrap link command, the symbol cli, or the symbol desktop wallet. ');
            logger.warn('The voting public key is stored in the target`s addresses.yml for reference');
            const metadata = {
                votingKeyStartEpoch: presetData.votingKeyStartEpoch,
                votingKeyEndEpoch: presetData.votingKeyEndEpoch,
                version: VotingService.METADATA_VERSION,
                votingPublicKey: nodeAccount.voting.publicKey,
            };
            await BootstrapUtils_1.BootstrapUtils.writeYaml(metadataFile, metadata, undefined);
        }
        else {
            logger.info(`Non-voting node ${nodeAccount.name}.`);
        }
    }
    async shouldGenerateVoting(presetData, metadataFile, votingAccount) {
        try {
            const metadata = BootstrapUtils_1.BootstrapUtils.loadYaml(metadataFile, false);
            return (metadata.votingPublicKey !== votingAccount.publicKey ||
                metadata.version !== VotingService.METADATA_VERSION ||
                metadata.votingKeyStartEpoch !== presetData.votingKeyStartEpoch ||
                metadata.votingKeyEndEpoch !== presetData.votingKeyEndEpoch);
        }
        catch (e) {
            return true;
        }
    }
}
exports.VotingService = VotingService;
VotingService.METADATA_VERSION = 1;
