"use strict";
// SPDX-License-Identifier: Apache-2.0
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const GetBondDetailsQuery_1 = require("../../../app/usecase/query/bond/get/getBondDetails/GetBondDetailsQuery");
const Injectable_1 = __importDefault(require("../../../core/injectable/Injectable"));
const LogErrorDecorator_1 = require("../../../core/decorator/LogErrorDecorator");
const QueryBus_1 = require("../../../core/query/QueryBus");
const ValidatedArgs_1 = __importDefault(require("../../../core/validation/ValidatedArgs"));
const GetBondDetailsRequest_1 = __importDefault(require("../request/bond/GetBondDetailsRequest"));
const GetAllCouponsRequest_1 = __importDefault(require("../request/bond/GetAllCouponsRequest"));
const GetCouponForRequest_1 = __importDefault(require("../request/bond/GetCouponForRequest"));
const GetPrincipalForRequest_1 = __importDefault(require("../request/bond/GetPrincipalForRequest"));
const GetCouponRequest_1 = __importDefault(require("../request/bond/GetCouponRequest"));
const GetCouponForQuery_1 = require("../../../app/usecase/query/bond/coupons/getCouponFor/GetCouponForQuery");
const GetCouponAmountForQuery_1 = require("../../../app/usecase/query/bond/coupons/getCouponAmountFor/GetCouponAmountForQuery");
const GetPrincipalForQuery_1 = require("../../../app/usecase/query/bond/get/getPrincipalFor/GetPrincipalForQuery");
const GetCouponQuery_1 = require("../../../app/usecase/query/bond/coupons/getCoupon/GetCouponQuery");
const GetCouponCountQuery_1 = require("../../../app/usecase/query/bond/coupons/getCouponCount/GetCouponCountQuery");
const SecurityDate_1 = require("../../../domain/context/shared/SecurityDate");
const CreateBondRequest_1 = __importDefault(require("../request/bond/CreateBondRequest"));
const CommandBus_1 = require("../../../core/command/CommandBus");
const NetworkService_1 = __importDefault(require("../../../app/service/network/NetworkService"));
const CreateBondCommand_1 = require("../../../app/usecase/command/bond/create/CreateBondCommand");
const ContractId_1 = __importDefault(require("../../../domain/context/contract/ContractId"));
const GetSecurityQuery_1 = require("../../../app/usecase/query/security/get/GetSecurityQuery");
const BigDecimal_1 = __importDefault(require("../../../domain/context/shared/BigDecimal"));
const SetCouponRequest_1 = __importDefault(require("../request/bond/SetCouponRequest"));
const SetCouponCommand_1 = require("../../../app/usecase/command/bond/coupon/set/SetCouponCommand");
const RegulationType_1 = require("../../../domain/context/factory/RegulationType");
const UpdateMaturityDateRequest_1 = __importDefault(require("../request/bond/UpdateMaturityDateRequest"));
const UpdateMaturityDateCommand_1 = require("../../../app/usecase/command/bond/updateMaturityDate/UpdateMaturityDateCommand");
const RedeemAtMaturityByPartitionCommand_1 = require("../../../app/usecase/command/bond/redeemAtMaturityByPartition/RedeemAtMaturityByPartitionCommand");
const FullRedeemAtMaturityCommand_1 = require("../../../app/usecase/command/bond/fullRedeemAtMaturity/FullRedeemAtMaturityCommand");
const RedeemAtMaturityByPartitionRequest_1 = __importDefault(require("../request/bond/RedeemAtMaturityByPartitionRequest"));
const FullRedeemAtMaturityRequest_1 = __importDefault(require("../request/bond/FullRedeemAtMaturityRequest"));
const GetCouponHoldersQuery_1 = require("../../../app/usecase/query/bond/coupons/getCouponHolders/GetCouponHoldersQuery");
const GetTotalCouponHoldersQuery_1 = require("../../../app/usecase/query/bond/coupons/getTotalCouponHolders/GetTotalCouponHoldersQuery");
const CreateTrexSuiteBondRequest_1 = __importDefault(require("../request/bond/CreateTrexSuiteBondRequest"));
const CreateTrexSuiteBondCommand_1 = require("../../../app/usecase/command/bond/createTrexSuite/CreateTrexSuiteBondCommand");
const AddProceedRecipientRequest_1 = __importDefault(require("../request/bond/AddProceedRecipientRequest"));
const RemoveProceedRecipientRequest_1 = __importDefault(require("../request/bond/RemoveProceedRecipientRequest"));
const UpdateProceedRecipientDataRequest_1 = __importDefault(require("../request/bond/UpdateProceedRecipientDataRequest"));
const UpdateProceedRecipientDataCommand_1 = require("../../../app/usecase/command/security/proceedRecipients/updateProceedRecipientData/UpdateProceedRecipientDataCommand");
const RemoveProceedRecipientCommand_1 = require("../../../app/usecase/command/security/proceedRecipients/removeProceedRecipient/RemoveProceedRecipientCommand");
const AddProceedRecipientCommand_1 = require("../../../app/usecase/command/security/proceedRecipients/addProceedRecipient/AddProceedRecipientCommand");
const IsProceedRecipientRequest_1 = __importDefault(require("../request/bond/IsProceedRecipientRequest"));
const GetProceedRecipientsQuery_1 = require("../../../app/usecase/query/security/proceedRecipient/getProceedRecipients/GetProceedRecipientsQuery");
const GetProceedRecipientsCountQuery_1 = require("../../../app/usecase/query/security/proceedRecipient/getProceedRecipientsCount/GetProceedRecipientsCountQuery");
const GetProceedRecipientDataQuery_1 = require("../../../app/usecase/query/security/proceedRecipient/getProceedRecipientData/GetProceedRecipientDataQuery");
const IsProceedRecipientQuery_1 = require("../../../app/usecase/query/security/proceedRecipient/isProceedRecipient/IsProceedRecipientQuery");
const request_1 = require("../request");
class BondInPort {
    constructor(queryBus = Injectable_1.default.resolve(QueryBus_1.QueryBus), commandBus = Injectable_1.default.resolve(CommandBus_1.CommandBus), networkService = Injectable_1.default.resolve(NetworkService_1.default)) {
        this.queryBus = queryBus;
        this.commandBus = commandBus;
        this.networkService = networkService;
    }
    async create(req) {
        ValidatedArgs_1.default.handleValidation('CreateBondRequest', req);
        const { diamondOwnerAccount, externalPausesIds, externalControlListsIds, externalKycListsIds, } = req;
        const securityFactory = this.networkService.configuration.factoryAddress;
        const resolver = this.networkService.configuration.resolverAddress;
        const newSecurity = {
            name: req.name,
            symbol: req.symbol,
            isin: req.isin,
            decimals: req.decimals,
            isWhiteList: req.isWhiteList,
            erc20VotesActivated: req.erc20VotesActivated,
            isControllable: req.isControllable,
            arePartitionsProtected: req.arePartitionsProtected,
            clearingActive: req.clearingActive,
            internalKycActivated: req.internalKycActivated,
            isMultiPartition: req.isMultiPartition,
            maxSupply: BigDecimal_1.default.fromString(req.numberOfUnits),
            regulationType: RegulationType_1.CastRegulationType.fromNumber(req.regulationType),
            regulationsubType: RegulationType_1.CastRegulationSubType.fromNumber(req.regulationSubType),
            isCountryControlListWhiteList: req.isCountryControlListWhiteList,
            countries: req.countries,
            info: req.info,
        };
        const createResponse = await this.commandBus.execute(new CreateBondCommand_1.CreateBondCommand(newSecurity, req.currency, req.nominalValue, req.nominalValueDecimals, req.startingDate, req.maturityDate, securityFactory ? new ContractId_1.default(securityFactory) : undefined, resolver ? new ContractId_1.default(resolver) : undefined, req.configId, req.configVersion, diamondOwnerAccount, externalPausesIds, externalControlListsIds, externalKycListsIds, req.complianceId, req.identityRegistryId, req.proceedRecipientsIds, req.proceedRecipientsData));
        const securityCreated = createResponse.securityId.toString() !== ContractId_1.default.NULL.toString();
        const res = securityCreated
            ? (await this.queryBus.execute(new GetSecurityQuery_1.GetSecurityQuery(createResponse.securityId.toString()))).security
            : {};
        return {
            security: securityCreated
                ? {
                    ...res,
                }
                : {},
            transactionId: createResponse.transactionId,
        };
    }
    async getBondDetails(request) {
        ValidatedArgs_1.default.handleValidation('GetBondDetailsRequest', request);
        const res = await this.queryBus.execute(new GetBondDetailsQuery_1.GetBondDetailsQuery(request.bondId));
        const bondDetails = {
            currency: res.bond.currency,
            nominalValue: res.bond.nominalValue.toString(),
            nominalValueDecimals: res.bond.nominalValueDecimals,
            startingDate: new Date(res.bond.startingDate * SecurityDate_1.ONE_THOUSAND),
            maturityDate: new Date(res.bond.maturityDate * SecurityDate_1.ONE_THOUSAND),
        };
        return bondDetails;
    }
    async setCoupon(request) {
        const { rate, recordTimestamp, executionTimestamp, securityId, period } = request;
        ValidatedArgs_1.default.handleValidation('SetCouponRequest', request);
        return await this.commandBus.execute(new SetCouponCommand_1.SetCouponCommand(securityId, recordTimestamp, executionTimestamp, rate, period));
    }
    async getCouponFor(request) {
        ValidatedArgs_1.default.handleValidation('GetCouponForRequest', request);
        const res = await this.queryBus.execute(new GetCouponForQuery_1.GetCouponForQuery(request.targetId, request.securityId, request.couponId));
        const couponFor = {
            value: res.payload.toString(),
        };
        return couponFor;
    }
    async getCouponAmountFor(request) {
        ValidatedArgs_1.default.handleValidation('GetCouponForRequest', request);
        const res = await this.queryBus.execute(new GetCouponAmountForQuery_1.GetCouponAmountForQuery(request.targetId, request.securityId, request.couponId));
        const couponAmountFor = {
            numerator: res.numerator,
            denominator: res.denominator,
            recordDateReached: res.recordDateReached,
        };
        return couponAmountFor;
    }
    async getPrincipalFor(request) {
        ValidatedArgs_1.default.handleValidation('GetPrincipalForRequest', request);
        const res = await this.queryBus.execute(new GetPrincipalForQuery_1.GetPrincipalForQuery(request.targetId, request.securityId));
        const principalFor = {
            numerator: res.numerator,
            denominator: res.denominator,
        };
        return principalFor;
    }
    async getCoupon(request) {
        ValidatedArgs_1.default.handleValidation('GetCouponRequest', request);
        const res = await this.queryBus.execute(new GetCouponQuery_1.GetCouponQuery(request.securityId, request.couponId));
        const coupon = {
            couponId: request.couponId,
            recordDate: new Date(res.coupon.recordTimeStamp * SecurityDate_1.ONE_THOUSAND),
            executionDate: new Date(res.coupon.executionTimeStamp * SecurityDate_1.ONE_THOUSAND),
            rate: res.coupon.rate.toString(),
            rateDecimals: res.coupon.rateDecimals,
            period: res.coupon.period,
        };
        return coupon;
    }
    async getAllCoupons(request) {
        ValidatedArgs_1.default.handleValidation('GetAllCouponsRequest', request);
        const count = await this.queryBus.execute(new GetCouponCountQuery_1.GetCouponCountQuery(request.securityId));
        if (count.payload == 0)
            return [];
        const coupons = [];
        for (let i = 1; i <= count.payload; i++) {
            const couponRequest = new GetCouponRequest_1.default({
                securityId: request.securityId,
                couponId: i,
            });
            const coupon = await this.getCoupon(couponRequest);
            coupons.push(coupon);
        }
        return coupons;
    }
    async updateMaturityDate(request) {
        const { maturityDate, securityId } = request;
        ValidatedArgs_1.default.handleValidation('UpdateMaturityDateRequest', request);
        return await this.commandBus.execute(new UpdateMaturityDateCommand_1.UpdateMaturityDateCommand(maturityDate, securityId));
    }
    async redeemAtMaturityByPartition(request) {
        const { securityId, partitionId, sourceId, amount } = request;
        ValidatedArgs_1.default.handleValidation(RedeemAtMaturityByPartitionRequest_1.default.name, request);
        return await this.commandBus.execute(new RedeemAtMaturityByPartitionCommand_1.RedeemAtMaturityByPartitionCommand(securityId, partitionId, sourceId, amount));
    }
    async fullRedeemAtMaturity(request) {
        const { securityId, sourceId } = request;
        ValidatedArgs_1.default.handleValidation(FullRedeemAtMaturityRequest_1.default.name, request);
        return await this.commandBus.execute(new FullRedeemAtMaturityCommand_1.FullRedeemAtMaturityCommand(securityId, sourceId));
    }
    async getCouponHolders(request) {
        const { securityId, couponId, start, end } = request;
        ValidatedArgs_1.default.handleValidation(request_1.GetCouponHoldersRequest.name, request);
        return (await this.queryBus.execute(new GetCouponHoldersQuery_1.GetCouponHoldersQuery(securityId, couponId, start, end))).payload;
    }
    async getTotalCouponHolders(request) {
        const { securityId, couponId } = request;
        ValidatedArgs_1.default.handleValidation(request_1.GetTotalCouponHoldersRequest.name, request);
        return (await this.queryBus.execute(new GetTotalCouponHoldersQuery_1.GetTotalCouponHoldersQuery(securityId, couponId))).payload;
    }
    async createTrexSuite(req) {
        ValidatedArgs_1.default.handleValidation('CreateTrexSuiteBondRequest', req);
        const { diamondOwnerAccount, externalPauses, externalControlLists, externalKycLists, } = req;
        const securityFactory = this.networkService.configuration.factoryAddress;
        const resolver = this.networkService.configuration.resolverAddress;
        const newSecurity = {
            name: req.name,
            symbol: req.symbol,
            isin: req.isin,
            decimals: req.decimals,
            isWhiteList: req.isWhiteList,
            isControllable: req.isControllable,
            arePartitionsProtected: req.arePartitionsProtected,
            clearingActive: req.clearingActive,
            internalKycActivated: req.internalKycActivated,
            isMultiPartition: req.isMultiPartition,
            maxSupply: BigDecimal_1.default.fromString(req.numberOfUnits),
            regulationType: RegulationType_1.CastRegulationType.fromNumber(req.regulationType),
            regulationsubType: RegulationType_1.CastRegulationSubType.fromNumber(req.regulationSubType),
            isCountryControlListWhiteList: req.isCountryControlListWhiteList,
            countries: req.countries,
            info: req.info,
            erc20VotesActivated: req.erc20VotesActivated,
        };
        const createResponse = await this.commandBus.execute(new CreateTrexSuiteBondCommand_1.CreateTrexSuiteBondCommand(req.salt, req.owner, req.irs, req.onchainId, req.irAgents, req.tokenAgents, req.compliancesModules, req.complianceSettings, req.claimTopics, req.issuers, req.issuerClaims, newSecurity, req.currency, req.nominalValue, req.nominalValueDecimals, req.startingDate, req.maturityDate, new ContractId_1.default(securityFactory), new ContractId_1.default(resolver), req.configId, req.configVersion, diamondOwnerAccount, req.proceedRecipientsIds, req.proceedRecipientsData, externalPauses, externalControlLists, externalKycLists, req.complianceId, req.identityRegistryId));
        const securityCreated = createResponse.securityId.toString() !== ContractId_1.default.NULL.toString();
        const res = securityCreated
            ? (await this.queryBus.execute(new GetSecurityQuery_1.GetSecurityQuery(createResponse.securityId.toString()))).security
            : {};
        return {
            security: securityCreated
                ? {
                    ...res,
                }
                : {},
            transactionId: createResponse.transactionId,
        };
    }
    async updateProceedRecipientData(request) {
        ValidatedArgs_1.default.handleValidation(UpdateProceedRecipientDataRequest_1.default.name, request);
        return await this.commandBus.execute(new UpdateProceedRecipientDataCommand_1.UpdateProceedRecipientDataCommand(request.securityId, request.proceedRecipientId, request.data));
    }
    async removeProceedRecipient(request) {
        ValidatedArgs_1.default.handleValidation(RemoveProceedRecipientRequest_1.default.name, request);
        return await this.commandBus.execute(new RemoveProceedRecipientCommand_1.RemoveProceedRecipientCommand(request.securityId, request.proceedRecipientId));
    }
    async addProceedRecipient(request) {
        ValidatedArgs_1.default.handleValidation(AddProceedRecipientRequest_1.default.name, request);
        return await this.commandBus.execute(new AddProceedRecipientCommand_1.AddProceedRecipientCommand(request.securityId, request.proceedRecipientId, request.data));
    }
    async getProceedRecipients(request) {
        ValidatedArgs_1.default.handleValidation(request_1.GetProceedRecipientsRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientsQuery_1.GetProceedRecipientsQuery(request.securityId, request.pageIndex, request.pageSize));
    }
    async getProceedRecipientsCount(request) {
        ValidatedArgs_1.default.handleValidation(request_1.GetProceedRecipientsCountRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientsCountQuery_1.GetProceedRecipientsCountQuery(request.securityId));
    }
    async getProceedRecipientData(request) {
        ValidatedArgs_1.default.handleValidation(request_1.GetProceedRecipientDataRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientDataQuery_1.GetProceedRecipientDataQuery(request.securityId, request.proceedRecipientId));
    }
    async isProceedRecipient(request) {
        ValidatedArgs_1.default.handleValidation(IsProceedRecipientRequest_1.default.name, request);
        return await this.queryBus.execute(new IsProceedRecipientQuery_1.IsProceedRecipientQuery(request.securityId, request.proceedRecipientId));
    }
}
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CreateBondRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "create", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetBondDetailsRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getBondDetails", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [SetCouponRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "setCoupon", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponForRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponFor", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponForRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponAmountFor", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetPrincipalForRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getPrincipalFor", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCoupon", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetAllCouponsRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getAllCoupons", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [UpdateMaturityDateRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "updateMaturityDate", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [RedeemAtMaturityByPartitionRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "redeemAtMaturityByPartition", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [FullRedeemAtMaturityRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "fullRedeemAtMaturity", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [request_1.GetCouponHoldersRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponHolders", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [request_1.GetTotalCouponHoldersRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getTotalCouponHolders", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CreateTrexSuiteBondRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "createTrexSuite", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [UpdateProceedRecipientDataRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "updateProceedRecipientData", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [RemoveProceedRecipientRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "removeProceedRecipient", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [AddProceedRecipientRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "addProceedRecipient", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [request_1.GetProceedRecipientsRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipients", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [request_1.GetProceedRecipientsCountRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipientsCount", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [request_1.GetProceedRecipientDataRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipientData", null);
__decorate([
    LogErrorDecorator_1.LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [IsProceedRecipientRequest_1.default]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "isProceedRecipient", null);
const BondToken = new BondInPort();
exports.default = BondToken;
