"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RewardProgramService = exports.RewardProgram = void 0;
/*
 * 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.
 */
const fs_1 = require("fs");
const path_1 = require("path");
const symbol_sdk_1 = require("symbol-sdk");
const LoggerFactory_1 = require("../logger/LoggerFactory");
const AnnounceService_1 = require("./AnnounceService");
const BootstrapUtils_1 = require("./BootstrapUtils");
const ConfigLoader_1 = require("./ConfigLoader");
const logger = LoggerFactory_1.default.getLogger();
var RewardProgram;
(function (RewardProgram) {
    RewardProgram["EarlyAdoption"] = "EarlyAdoption";
    RewardProgram["Ecosystem"] = "Ecosystem";
    RewardProgram["SuperNode"] = "SuperNode";
    RewardProgram["MonitorOnly"] = "MonitorOnly";
})(RewardProgram = exports.RewardProgram || (exports.RewardProgram = {}));
class RewardProgramService {
    constructor(params) {
        this.params = params;
        this.configLoader = new ConfigLoader_1.ConfigLoader();
    }
    static getRewardProgram(value) {
        const programs = Object.values(RewardProgram);
        const program = programs.find((p) => p.toLowerCase() == value.toLowerCase());
        if (program) {
            return program;
        }
        throw new BootstrapUtils_1.KnownError(`${value} is not a valid Reward program. Please use one of ${programs.join(', ')}`);
    }
    async enroll(passedPresetData, passedAddresses) {
        const presetData = passedPresetData !== null && passedPresetData !== void 0 ? passedPresetData : this.configLoader.loadExistingPresetData(this.params.target, this.params.password);
        const addresses = passedAddresses !== null && passedAddresses !== void 0 ? passedAddresses : this.configLoader.loadExistingAddresses(this.params.target, this.params.password);
        const customPreset = this.configLoader.loadCustomPreset(this.params.customPreset, this.params.password);
        if (!presetData.rewardProgramEnrollmentAddress) {
            logger.warn('This network does not have a reward program controller public key. Nodes cannot be registered.');
            return;
        }
        await new AnnounceService_1.AnnounceService().announce(this.params.url, this.params.maxFee, this.params.useKnownRestGateways, this.params.ready, this.params.target, this.configLoader.mergePresets(presetData, customPreset), addresses, this, '1M+');
    }
    async createTransactions({ presetData, nodePreset, nodeAccount, deadline, maxFee, }) {
        const transactions = [];
        const networkType = presetData.networkType;
        if (!nodePreset.rewardProgram) {
            logger.warn(`Node ${nodeAccount.name} hasn't been configured with rewardProgram: preset property.`);
            return transactions;
        }
        if (!presetData.rewardProgramEnrollmentAddress) {
            return transactions;
        }
        const rewardProgramEnrollmentAddress = symbol_sdk_1.Address.createFromRawAddress(presetData.rewardProgramEnrollmentAddress);
        const agentPublicKey = nodeAccount.transport.publicKey;
        if (!agentPublicKey) {
            logger.warn(`Cannot resolve harvester public key of node ${nodeAccount.name}`);
            return transactions;
        }
        if (!nodePreset.host) {
            logger.warn(`Node ${nodeAccount.name} public host name hasn't been provided! Please use 'host: myNodeHost' custom preset param.`);
            return transactions;
        }
        const agentUrl = nodePreset.agentUrl || `https://${nodePreset.host}:${nodePreset.rewardProgramAgentPort || presetData.rewardProgramAgentPort}`;
        const certFolder = BootstrapUtils_1.BootstrapUtils.getTargetNodesFolder(this.params.target, false, nodePreset.name, 'agent');
        const base64AgentCaCsrFile = fs_1.readFileSync(path_1.join(certFolder, 'agent-ca.csr.pem'), 'base64');
        const plainMessage = `enroll ${agentUrl} ${base64AgentCaCsrFile}`;
        const message = symbol_sdk_1.PlainMessage.create(plainMessage);
        logger.info(`Creating enrolment transfer with message '${plainMessage}'`);
        const transaction = symbol_sdk_1.TransferTransaction.create(deadline, rewardProgramEnrollmentAddress, [], message, networkType, maxFee);
        return [transaction];
    }
}
exports.RewardProgramService = RewardProgramService;
RewardProgramService.defaultParams = {
    useKnownRestGateways: false,
    target: BootstrapUtils_1.BootstrapUtils.defaultTargetFolder,
    url: 'http://localhost:3000',
};
