"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.Requirements = void 0;
const internal_1 = require("../../../../internal");
const conversion_1 = require("../../../../utils/conversion");
const internal_2 = require("../../../../utils/internal");
/**
 * Handles all Security Token Compliance Requirements related functionality
 */
class Requirements extends internal_1.Namespace {
    /**
     * @hidden
     */
    constructor(parent, context) {
        super(parent, context);
        const { ticker } = parent;
        this.add = internal_2.createProcedureMethod({ getProcedureAndArgs: args => [internal_1.addAssetRequirement, Object.assign({ ticker }, args)] }, context);
        this.remove = internal_2.createProcedureMethod({ getProcedureAndArgs: args => [internal_1.removeAssetRequirement, Object.assign({ ticker }, args)] }, context);
        this.set = internal_2.createProcedureMethod({ getProcedureAndArgs: args => [internal_1.setAssetRequirements, Object.assign({ ticker }, args)] }, context);
        this.reset = internal_2.createProcedureMethod({
            getProcedureAndArgs: () => [internal_1.setAssetRequirements, { ticker, requirements: [] }],
            voidArgs: true,
        }, context);
        this.pause = internal_2.createProcedureMethod({
            getProcedureAndArgs: () => [internal_1.togglePauseRequirements, { ticker, pause: true }],
            voidArgs: true,
        }, context);
        this.unpause = internal_2.createProcedureMethod({
            getProcedureAndArgs: () => [internal_1.togglePauseRequirements, { ticker, pause: false }],
            voidArgs: true,
        }, context);
        this.modify = internal_2.createProcedureMethod({ getProcedureAndArgs: args => [internal_1.modifyComplianceRequirement, Object.assign({ ticker }, args)] }, context);
    }
    // eslint-disable-next-line require-jsdoc
    get(callback) {
        return __awaiter(this, void 0, void 0, function* () {
            const { parent: { ticker }, context: { polymeshApi: { query: { complianceManager }, queryMulti, }, }, context, } = this;
            const rawTicker = conversion_1.stringToTicker(ticker, context);
            const assembleResult = ([assetCompliance, claimIssuers]) => {
                const requirements = assetCompliance.requirements.map(complianceRequirement => conversion_1.complianceRequirementToRequirement(complianceRequirement, context));
                const defaultTrustedClaimIssuers = claimIssuers.map(issuer => conversion_1.trustedIssuerToTrustedClaimIssuer(issuer, context));
                return { requirements, defaultTrustedClaimIssuers };
            };
            if (callback) {
                return queryMulti([
                    [
                        complianceManager.assetCompliances,
                        rawTicker,
                    ],
                    [
                        complianceManager.trustedClaimIssuer,
                        rawTicker,
                    ],
                ], res => {
                    callback(assembleResult(res));
                });
            }
            const result = yield queryMulti([
                [
                    complianceManager.assetCompliances,
                    rawTicker,
                ],
                [
                    complianceManager.trustedClaimIssuer,
                    rawTicker,
                ],
            ]);
            return assembleResult(result);
        });
    }
    /**
     * Check whether the sender and receiver Identities in a transfer comply with all the requirements of this asset
     *
     * @note this does not take balances into account
     *
     * @param args.from - sender Identity (optional, defaults to the current Identity)
     * @param args.to - receiver Identity
     *
     * @deprecated in favor of `settlements.canTransfer`
     */
    checkSettle(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const { parent: { ticker }, context: { polymeshApi: { rpc }, }, context, } = this;
            const { from = yield context.getCurrentIdentity(), to } = args;
            const fromDid = conversion_1.stringToIdentityId(conversion_1.signerToString(from), context);
            const toDid = conversion_1.signerToString(to);
            const res = yield rpc.compliance.canTransfer(conversion_1.stringToTicker(ticker, context), fromDid, conversion_1.stringToIdentityId(toDid, context));
            return conversion_1.assetComplianceResultToCompliance(res, context);
        });
    }
    /**
     * Check whether asset compliance requirements are paused or not
     */
    arePaused() {
        return __awaiter(this, void 0, void 0, function* () {
            const { parent: { ticker }, context: { polymeshApi: { query: { complianceManager }, }, }, context, } = this;
            const rawTicker = conversion_1.stringToTicker(ticker, context);
            const { paused } = yield complianceManager.assetCompliances(rawTicker);
            return conversion_1.boolToBoolean(paused);
        });
    }
}
exports.Requirements = Requirements;
//# sourceMappingURL=Requirements.js.map