"use strict";
/*
 *
 * Copyright 2018-present 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.HdProfile = void 0;
const clime_1 = require("clime");
const symbol_sdk_1 = require("symbol-sdk");
const derivation_service_1 = require("../services/derivation.service");
const signing_service_1 = require("../services/signing.service");
const networkCurrency_model_1 = require("./networkCurrency.model");
const profile_model_1 = require("./profile.model");
/**
 * Hd Profile model
 * @export
 * @class HdProfile
 * @extends {Profile}
 */
class HdProfile extends profile_model_1.Profile {
    /**
     * Creates an instance of HdProfile.
     * @param {SimpleWallet} simpleWallet
     * @param {string} url
     * @param {string} networkGenerationHash
     * @param {number} epochAdjustment
     * @param {NetworkCurrency} networkCurrency
     * @param {number} version
     * @param {ProfileType} type
     * @param {('0' | '1')} isDefault
     * @param {string} encryptedPassphrase
     * @param {string} path
     */
    constructor(simpleWallet, url, networkGenerationHash, epochAdjustment, networkCurrency, version, type, isDefault, encryptedPassphrase, path) {
        super(simpleWallet, url, networkGenerationHash, epochAdjustment, networkCurrency, version, type, isDefault);
        this.encryptedPassphrase = encryptedPassphrase;
        this.path = path;
    }
    /**
     * Creates a new HD Profile from a DTO
     * @static
     * @param {HdProfileDTO} DTO
     * @returns {HdProfile}
     */
    static createFromDTO(DTO) {
        return new HdProfile(symbol_sdk_1.SimpleWallet.createFromDTO(DTO.simpleWallet), DTO.url, DTO.networkGenerationHash, DTO.epochAdjustment || profile_model_1.epochAdjustment, networkCurrency_model_1.NetworkCurrency.createFromDTO(DTO.networkCurrency), DTO.version, DTO.type, DTO.default, DTO.encryptedPassphrase, DTO.path);
    }
    /**
     * Creates a new HD Profile
     * @static
     * @param {HdProfileCreation} args
     * @returns
     */
    static create(args) {
        let privateKey = '';
        if (args.optin) {
            privateKey = derivation_service_1.DerivationService.getPrivateKeyFromOptinMnemonic(args.mnemonic, args.pathNumber, args.networkType);
        }
        else {
            privateKey = derivation_service_1.DerivationService.getPrivateKeyFromMnemonic(args.mnemonic, args.pathNumber, args.networkType);
        }
        const path = derivation_service_1.DerivationService.getPathFromPathNumber(args.pathNumber, args.networkType);
        const simpleWallet = symbol_sdk_1.SimpleWallet.createFromPrivateKey(args.name, args.password, privateKey, args.networkType);
        return new HdProfile(simpleWallet, args.url, args.generationHash, args.epochAdjustment || profile_model_1.epochAdjustment, args.networkCurrency, profile_model_1.CURRENT_PROFILE_VERSION, 'HD', args.isDefault ? '1' : '0', symbol_sdk_1.Crypto.encrypt(args.mnemonic, args.password.value), path);
    }
    /**
     * Gets path number
     * @returns {(number | null)}
     */
    get pathNumber() {
        return derivation_service_1.DerivationService.getPathIndexFromPath(this.path);
    }
    /**
     * Creates a DTO
     * @returns {HdProfileDTO}
     */
    toDTO() {
        return {
            simpleWallet: this.simpleWallet.toDTO(),
            url: this.url,
            networkGenerationHash: this.networkGenerationHash,
            epochAdjustment: this.epochAdjustment,
            networkCurrency: this.networkCurrency.toDTO(),
            version: this.version,
            default: this.isDefault,
            type: this.type,
            encryptedPassphrase: this.encryptedPassphrase,
            path: this.path,
        };
    }
    /**
     * Returns true if the password is valid.
     * @param {Password} password.
     * @returns {boolean}
     */
    isPasswordValid(password) {
        try {
            this.simpleWallet.open(password);
            return true;
        }
        catch (error) {
            return false;
        }
    }
    /**
     * Opens a wallet.
     * @param password The  attribute "password" should contain the profile's password.
     */
    decrypt(password) {
        if (!this.isPasswordValid(password)) {
            throw new clime_1.ExpectedError('The password provided does not match your account password');
        }
        return this.simpleWallet.open(password);
    }
    getTable(password) {
        const table = this.getBaseTable();
        if (password) {
            table.push(['Password', password.value]);
            table.push(['Mnemonic', symbol_sdk_1.Crypto.decrypt(this.encryptedPassphrase, password.value)]);
            table.push(['Private key', this.decrypt(password).privateKey]);
        }
        table.push(['Path', `Path n. ${this.pathNumber + 1} (${this.path})`]);
        return table;
    }
    async getSigningAccount(passwordResolver) {
        return new signing_service_1.PrivateKeyAccount(this.decrypt(await passwordResolver()));
    }
}
exports.HdProfile = HdProfile;
