"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isFullGroupType = exports.assertDistributionDatesValid = exports.assertCaCheckpointValid = exports.assertCaTaxWithholdingsValid = exports.assertCaTargetsValid = exports.assertDistributionOpen = exports.assertSecondaryKeys = exports.assertPortfolioExists = exports.assertInstructionValid = void 0;
const internal_1 = require("../../internal");
const types_1 = require("../../types");
const conversion_1 = require("../../utils/conversion");
// import { Proposal } from '~/internal';
// import { ProposalStage, ProposalState } from '~/api/entities/Proposal/types';
// import { Context, PolymeshError } from '~/internal';
// import { ErrorCode } from '~/types';
// /**
//  * @hidden
//  */
// export async function assertProposalUnlocked(pipId: BigNumber, context: Context): Promise<void> {
//   const proposal = new Proposal({ pipId }, context);
//   const [details, stage] = await Promise.all([proposal.getDetails(), proposal.getStage()]);
//   const { lastState } = details;
//   if (lastState !== ProposalState.Pending) {
//     throw new PolymeshError({
//       code: ErrorCode.ValidationError,
//       message: 'The proposal must be in pending state',
//     });
//   }
//   if (stage !== ProposalStage.CoolOff) {
//     throw new PolymeshError({
//       code: ErrorCode.ValidationError,
//       message: 'The proposal must be in its cool-off period',
//     });
//   }
// }
/**
 * @hidden
 */
function assertInstructionValid(instruction, context) {
    return __awaiter(this, void 0, void 0, function* () {
        const details = yield instruction.details();
        const { status } = yield instruction.details();
        if (status !== types_1.InstructionStatus.Pending) {
            throw new internal_1.PolymeshError({
                code: types_1.ErrorCode.UnmetPrerequisite,
                message: 'The Instruction must be in pending state',
            });
        }
        if (details.type === types_1.InstructionType.SettleOnBlock) {
            const latestBlock = yield context.getLatestBlock();
            const { endBlock } = details;
            if (latestBlock >= endBlock) {
                throw new internal_1.PolymeshError({
                    code: types_1.ErrorCode.UnmetPrerequisite,
                    message: 'The Instruction cannot be modified; it has already reached its end block',
                    data: {
                        currentBlock: latestBlock,
                        endBlock,
                    },
                });
            }
        }
    });
}
exports.assertInstructionValid = assertInstructionValid;
/**
 * @hidden
 */
function assertPortfolioExists(portfolioId, context) {
    return __awaiter(this, void 0, void 0, function* () {
        const { did, number } = portfolioId;
        if (number) {
            const numberedPortfolio = new internal_1.NumberedPortfolio({ did, id: number }, context);
            const exists = yield numberedPortfolio.exists();
            if (!exists) {
                throw new internal_1.PolymeshError({
                    code: types_1.ErrorCode.DataUnavailable,
                    message: "The Portfolio doesn't exist",
                    data: {
                        did,
                        portfolioId: number,
                    },
                });
            }
        }
    });
}
exports.assertPortfolioExists = assertPortfolioExists;
/**
 * @hidden
 */
function assertSecondaryKeys(signerValues, secondaryKeys) {
    const notInTheList = [];
    signerValues.forEach(({ value: itemValue }) => {
        const isPresent = secondaryKeys
            .map(({ signer }) => conversion_1.signerToSignerValue(signer))
            .find(({ value }) => value === itemValue);
        if (!isPresent) {
            notInTheList.push(itemValue);
        }
    });
    if (notInTheList.length) {
        throw new internal_1.PolymeshError({
            code: types_1.ErrorCode.UnmetPrerequisite,
            message: 'One of the Signers is not a Secondary Key for the Identity',
            data: {
                missing: notInTheList,
            },
        });
    }
}
exports.assertSecondaryKeys = assertSecondaryKeys;
/**
 * @hidden
 */
function assertDistributionOpen(paymentDate, expiryDate) {
    const now = new Date();
    if (paymentDate > now) {
        throw new internal_1.PolymeshError({
            code: types_1.ErrorCode.UnmetPrerequisite,
            message: "The Distribution's payment date hasn't been reached",
            data: { paymentDate },
        });
    }
    if (expiryDate && expiryDate < now) {
        throw new internal_1.PolymeshError({
            code: types_1.ErrorCode.UnmetPrerequisite,
            message: 'The Distribution has already expired',
            data: {
                expiryDate,
            },
        });
    }
}
exports.assertDistributionOpen = assertDistributionOpen;
/**
 * @hidden
 */
function assertCaTargetsValid(targets, context) {
    const { maxTargetIds } = context.polymeshApi.consts.corporateAction;
    const maxTargets = conversion_1.u64ToBigNumber(maxTargetIds);
    if (maxTargets.lt(targets.identities.length)) {
        throw new internal_1.PolymeshError({
            code: types_1.ErrorCode.ValidationError,
            message: 'Too many target Identities',
            data: {
                maxTargets,
            },
        });
    }
}
exports.assertCaTargetsValid = assertCaTargetsValid;
/**
 * @hidden
 */
function assertCaTaxWithholdingsValid(taxWithholdings, context) {
    const { maxDidWhts } = context.polymeshApi.consts.corporateAction;
    const maxWithholdingEntries = conversion_1.u64ToBigNumber(maxDidWhts);
    if (maxWithholdingEntries.lt(taxWithholdings.length)) {
        throw new internal_1.PolymeshError({
            code: types_1.ErrorCode.ValidationError,
            message: 'Too many tax withholding entries',
            data: {
                maxWithholdingEntries,
            },
        });
    }
}
exports.assertCaTaxWithholdingsValid = assertCaTaxWithholdingsValid;
/**
 * @hidden
 */
function assertCaCheckpointValid(checkpoint) {
    return __awaiter(this, void 0, void 0, function* () {
        if (checkpoint instanceof Date) {
            if (checkpoint <= new Date()) {
                throw new internal_1.PolymeshError({
                    code: types_1.ErrorCode.ValidationError,
                    message: 'Checkpoint date must be in the future',
                });
            }
        }
        else {
            const exists = yield checkpoint.exists();
            if (!exists) {
                throw new internal_1.PolymeshError({
                    code: types_1.ErrorCode.DataUnavailable,
                    message: checkpoint instanceof internal_1.Checkpoint
                        ? "Checkpoint doesn't exist"
                        : "Checkpoint Schedule doesn't exist",
                });
            }
        }
    });
}
exports.assertCaCheckpointValid = assertCaCheckpointValid;
/**
 * @hidden
 */
function assertDistributionDatesValid(checkpoint, paymentDate, expiryDate) {
    return __awaiter(this, void 0, void 0, function* () {
        let checkpointDate;
        if (checkpoint instanceof Date) {
            checkpointDate = checkpoint;
        }
        else {
            ({ nextCheckpointDate: checkpointDate } = yield checkpoint.details());
        }
        if (paymentDate <= checkpointDate) {
            throw new internal_1.PolymeshError({
                code: types_1.ErrorCode.ValidationError,
                message: 'Payment date must be after the Checkpoint date',
            });
        }
        if (expiryDate && expiryDate < checkpointDate) {
            throw new internal_1.PolymeshError({
                code: types_1.ErrorCode.ValidationError,
                message: 'Expiry date must be after the Checkpoint date',
            });
        }
    });
}
exports.assertDistributionDatesValid = assertDistributionDatesValid;
/**
 * @hidden
 */
function isFullGroupType(group) {
    return group instanceof internal_1.KnownPermissionGroup && group.type === types_1.PermissionGroupType.Full;
}
exports.isFullGroupType = isFullGroupType;
//# sourceMappingURL=utils.js.map