// 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);
};
import { GetBondDetailsQuery } from '../../../app/usecase/query/bond/get/getBondDetails/GetBondDetailsQuery';
import Injectable from '../../../core/injectable/Injectable';
import { LogError } from '../../../core/decorator/LogErrorDecorator';
import { QueryBus } from '../../../core/query/QueryBus';
import ValidatedRequest from '../../../core/validation/ValidatedArgs';
import GetBondDetailsRequest from '../request/bond/GetBondDetailsRequest';
import GetAllCouponsRequest from '../request/bond/GetAllCouponsRequest';
import GetCouponForRequest from '../request/bond/GetCouponForRequest';
import GetPrincipalForRequest from '../request/bond/GetPrincipalForRequest';
import GetCouponRequest from '../request/bond/GetCouponRequest';
import { GetCouponForQuery } from '../../../app/usecase/query/bond/coupons/getCouponFor/GetCouponForQuery';
import { GetCouponAmountForQuery } from '../../../app/usecase/query/bond/coupons/getCouponAmountFor/GetCouponAmountForQuery';
import { GetPrincipalForQuery } from '../../../app/usecase/query/bond/get/getPrincipalFor/GetPrincipalForQuery';
import { GetCouponQuery } from '../../../app/usecase/query/bond/coupons/getCoupon/GetCouponQuery';
import { GetCouponCountQuery } from '../../../app/usecase/query/bond/coupons/getCouponCount/GetCouponCountQuery';
import { ONE_THOUSAND } from '../../../domain/context/shared/SecurityDate';
import CreateBondRequest from '../request/bond/CreateBondRequest';
import { CommandBus } from '../../../core/command/CommandBus';
import NetworkService from '../../../app/service/network/NetworkService';
import { CreateBondCommand } from '../../../app/usecase/command/bond/create/CreateBondCommand';
import ContractId from '../../../domain/context/contract/ContractId';
import { GetSecurityQuery } from '../../../app/usecase/query/security/get/GetSecurityQuery';
import BigDecimal from '../../../domain/context/shared/BigDecimal';
import SetCouponRequest from '../request/bond/SetCouponRequest';
import { SetCouponCommand } from '../../../app/usecase/command/bond/coupon/set/SetCouponCommand';
import { CastRegulationSubType, CastRegulationType, } from '../../../domain/context/factory/RegulationType';
import UpdateMaturityDateRequest from '../request/bond/UpdateMaturityDateRequest';
import { UpdateMaturityDateCommand } from '../../../app/usecase/command/bond/updateMaturityDate/UpdateMaturityDateCommand';
import { RedeemAtMaturityByPartitionCommand } from '../../../app/usecase/command/bond/redeemAtMaturityByPartition/RedeemAtMaturityByPartitionCommand';
import { FullRedeemAtMaturityCommand } from '../../../app/usecase/command/bond/fullRedeemAtMaturity/FullRedeemAtMaturityCommand';
import RedeemAtMaturityByPartitionRequest from '../request/bond/RedeemAtMaturityByPartitionRequest';
import FullRedeemAtMaturityRequest from '../request/bond/FullRedeemAtMaturityRequest';
import { GetCouponHoldersQuery } from '../../../app/usecase/query/bond/coupons/getCouponHolders/GetCouponHoldersQuery';
import { GetTotalCouponHoldersQuery } from '../../../app/usecase/query/bond/coupons/getTotalCouponHolders/GetTotalCouponHoldersQuery';
import CreateTrexSuiteBondRequest from '../request/bond/CreateTrexSuiteBondRequest';
import { CreateTrexSuiteBondCommand } from '../../../app/usecase/command/bond/createTrexSuite/CreateTrexSuiteBondCommand';
import AddProceedRecipientRequest from '../request/bond/AddProceedRecipientRequest';
import RemoveProceedRecipientRequest from '../request/bond/RemoveProceedRecipientRequest';
import UpdateProceedRecipientDataRequest from '../request/bond/UpdateProceedRecipientDataRequest';
import { UpdateProceedRecipientDataCommand } from '../../../app/usecase/command/security/proceedRecipients/updateProceedRecipientData/UpdateProceedRecipientDataCommand';
import { RemoveProceedRecipientCommand } from '../../../app/usecase/command/security/proceedRecipients/removeProceedRecipient/RemoveProceedRecipientCommand';
import { AddProceedRecipientCommand } from '../../../app/usecase/command/security/proceedRecipients/addProceedRecipient/AddProceedRecipientCommand';
import IsProceedRecipientRequest from '../request/bond/IsProceedRecipientRequest';
import { GetProceedRecipientsQuery } from '../../../app/usecase/query/security/proceedRecipient/getProceedRecipients/GetProceedRecipientsQuery';
import { GetProceedRecipientsCountQuery } from '../../../app/usecase/query/security/proceedRecipient/getProceedRecipientsCount/GetProceedRecipientsCountQuery';
import { GetProceedRecipientDataQuery } from '../../../app/usecase/query/security/proceedRecipient/getProceedRecipientData/GetProceedRecipientDataQuery';
import { IsProceedRecipientQuery } from '../../../app/usecase/query/security/proceedRecipient/isProceedRecipient/IsProceedRecipientQuery';
import { GetCouponHoldersRequest, GetTotalCouponHoldersRequest, GetProceedRecipientDataRequest, GetProceedRecipientsCountRequest, GetProceedRecipientsRequest, } from '../request';
class BondInPort {
    constructor(queryBus = Injectable.resolve(QueryBus), commandBus = Injectable.resolve(CommandBus), networkService = Injectable.resolve(NetworkService)) {
        this.queryBus = queryBus;
        this.commandBus = commandBus;
        this.networkService = networkService;
    }
    async create(req) {
        ValidatedRequest.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.fromString(req.numberOfUnits),
            regulationType: CastRegulationType.fromNumber(req.regulationType),
            regulationsubType: CastRegulationSubType.fromNumber(req.regulationSubType),
            isCountryControlListWhiteList: req.isCountryControlListWhiteList,
            countries: req.countries,
            info: req.info,
        };
        const createResponse = await this.commandBus.execute(new CreateBondCommand(newSecurity, req.currency, req.nominalValue, req.nominalValueDecimals, req.startingDate, req.maturityDate, securityFactory ? new ContractId(securityFactory) : undefined, resolver ? new ContractId(resolver) : undefined, req.configId, req.configVersion, diamondOwnerAccount, externalPausesIds, externalControlListsIds, externalKycListsIds, req.complianceId, req.identityRegistryId, req.proceedRecipientsIds, req.proceedRecipientsData));
        const securityCreated = createResponse.securityId.toString() !== ContractId.NULL.toString();
        const res = securityCreated
            ? (await this.queryBus.execute(new GetSecurityQuery(createResponse.securityId.toString()))).security
            : {};
        return {
            security: securityCreated
                ? {
                    ...res,
                }
                : {},
            transactionId: createResponse.transactionId,
        };
    }
    async getBondDetails(request) {
        ValidatedRequest.handleValidation('GetBondDetailsRequest', request);
        const res = await this.queryBus.execute(new GetBondDetailsQuery(request.bondId));
        const bondDetails = {
            currency: res.bond.currency,
            nominalValue: res.bond.nominalValue.toString(),
            nominalValueDecimals: res.bond.nominalValueDecimals,
            startingDate: new Date(res.bond.startingDate * ONE_THOUSAND),
            maturityDate: new Date(res.bond.maturityDate * ONE_THOUSAND),
        };
        return bondDetails;
    }
    async setCoupon(request) {
        const { rate, recordTimestamp, executionTimestamp, securityId, period } = request;
        ValidatedRequest.handleValidation('SetCouponRequest', request);
        return await this.commandBus.execute(new SetCouponCommand(securityId, recordTimestamp, executionTimestamp, rate, period));
    }
    async getCouponFor(request) {
        ValidatedRequest.handleValidation('GetCouponForRequest', request);
        const res = await this.queryBus.execute(new GetCouponForQuery(request.targetId, request.securityId, request.couponId));
        const couponFor = {
            value: res.payload.toString(),
        };
        return couponFor;
    }
    async getCouponAmountFor(request) {
        ValidatedRequest.handleValidation('GetCouponForRequest', request);
        const res = await this.queryBus.execute(new GetCouponAmountForQuery(request.targetId, request.securityId, request.couponId));
        const couponAmountFor = {
            numerator: res.numerator,
            denominator: res.denominator,
            recordDateReached: res.recordDateReached,
        };
        return couponAmountFor;
    }
    async getPrincipalFor(request) {
        ValidatedRequest.handleValidation('GetPrincipalForRequest', request);
        const res = await this.queryBus.execute(new GetPrincipalForQuery(request.targetId, request.securityId));
        const principalFor = {
            numerator: res.numerator,
            denominator: res.denominator,
        };
        return principalFor;
    }
    async getCoupon(request) {
        ValidatedRequest.handleValidation('GetCouponRequest', request);
        const res = await this.queryBus.execute(new GetCouponQuery(request.securityId, request.couponId));
        const coupon = {
            couponId: request.couponId,
            recordDate: new Date(res.coupon.recordTimeStamp * ONE_THOUSAND),
            executionDate: new Date(res.coupon.executionTimeStamp * ONE_THOUSAND),
            rate: res.coupon.rate.toString(),
            rateDecimals: res.coupon.rateDecimals,
            period: res.coupon.period,
        };
        return coupon;
    }
    async getAllCoupons(request) {
        ValidatedRequest.handleValidation('GetAllCouponsRequest', request);
        const count = await this.queryBus.execute(new GetCouponCountQuery(request.securityId));
        if (count.payload == 0)
            return [];
        const coupons = [];
        for (let i = 1; i <= count.payload; i++) {
            const couponRequest = new GetCouponRequest({
                securityId: request.securityId,
                couponId: i,
            });
            const coupon = await this.getCoupon(couponRequest);
            coupons.push(coupon);
        }
        return coupons;
    }
    async updateMaturityDate(request) {
        const { maturityDate, securityId } = request;
        ValidatedRequest.handleValidation('UpdateMaturityDateRequest', request);
        return await this.commandBus.execute(new UpdateMaturityDateCommand(maturityDate, securityId));
    }
    async redeemAtMaturityByPartition(request) {
        const { securityId, partitionId, sourceId, amount } = request;
        ValidatedRequest.handleValidation(RedeemAtMaturityByPartitionRequest.name, request);
        return await this.commandBus.execute(new RedeemAtMaturityByPartitionCommand(securityId, partitionId, sourceId, amount));
    }
    async fullRedeemAtMaturity(request) {
        const { securityId, sourceId } = request;
        ValidatedRequest.handleValidation(FullRedeemAtMaturityRequest.name, request);
        return await this.commandBus.execute(new FullRedeemAtMaturityCommand(securityId, sourceId));
    }
    async getCouponHolders(request) {
        const { securityId, couponId, start, end } = request;
        ValidatedRequest.handleValidation(GetCouponHoldersRequest.name, request);
        return (await this.queryBus.execute(new GetCouponHoldersQuery(securityId, couponId, start, end))).payload;
    }
    async getTotalCouponHolders(request) {
        const { securityId, couponId } = request;
        ValidatedRequest.handleValidation(GetTotalCouponHoldersRequest.name, request);
        return (await this.queryBus.execute(new GetTotalCouponHoldersQuery(securityId, couponId))).payload;
    }
    async createTrexSuite(req) {
        ValidatedRequest.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.fromString(req.numberOfUnits),
            regulationType: CastRegulationType.fromNumber(req.regulationType),
            regulationsubType: CastRegulationSubType.fromNumber(req.regulationSubType),
            isCountryControlListWhiteList: req.isCountryControlListWhiteList,
            countries: req.countries,
            info: req.info,
            erc20VotesActivated: req.erc20VotesActivated,
        };
        const createResponse = await this.commandBus.execute(new 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(securityFactory), new ContractId(resolver), req.configId, req.configVersion, diamondOwnerAccount, req.proceedRecipientsIds, req.proceedRecipientsData, externalPauses, externalControlLists, externalKycLists, req.complianceId, req.identityRegistryId));
        const securityCreated = createResponse.securityId.toString() !== ContractId.NULL.toString();
        const res = securityCreated
            ? (await this.queryBus.execute(new GetSecurityQuery(createResponse.securityId.toString()))).security
            : {};
        return {
            security: securityCreated
                ? {
                    ...res,
                }
                : {},
            transactionId: createResponse.transactionId,
        };
    }
    async updateProceedRecipientData(request) {
        ValidatedRequest.handleValidation(UpdateProceedRecipientDataRequest.name, request);
        return await this.commandBus.execute(new UpdateProceedRecipientDataCommand(request.securityId, request.proceedRecipientId, request.data));
    }
    async removeProceedRecipient(request) {
        ValidatedRequest.handleValidation(RemoveProceedRecipientRequest.name, request);
        return await this.commandBus.execute(new RemoveProceedRecipientCommand(request.securityId, request.proceedRecipientId));
    }
    async addProceedRecipient(request) {
        ValidatedRequest.handleValidation(AddProceedRecipientRequest.name, request);
        return await this.commandBus.execute(new AddProceedRecipientCommand(request.securityId, request.proceedRecipientId, request.data));
    }
    async getProceedRecipients(request) {
        ValidatedRequest.handleValidation(GetProceedRecipientsRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientsQuery(request.securityId, request.pageIndex, request.pageSize));
    }
    async getProceedRecipientsCount(request) {
        ValidatedRequest.handleValidation(GetProceedRecipientsCountRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientsCountQuery(request.securityId));
    }
    async getProceedRecipientData(request) {
        ValidatedRequest.handleValidation(GetProceedRecipientDataRequest.name, request);
        return await this.queryBus.execute(new GetProceedRecipientDataQuery(request.securityId, request.proceedRecipientId));
    }
    async isProceedRecipient(request) {
        ValidatedRequest.handleValidation(IsProceedRecipientRequest.name, request);
        return await this.queryBus.execute(new IsProceedRecipientQuery(request.securityId, request.proceedRecipientId));
    }
}
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CreateBondRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "create", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetBondDetailsRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getBondDetails", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [SetCouponRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "setCoupon", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponForRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponFor", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponForRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponAmountFor", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetPrincipalForRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getPrincipalFor", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCoupon", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetAllCouponsRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getAllCoupons", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [UpdateMaturityDateRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "updateMaturityDate", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [RedeemAtMaturityByPartitionRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "redeemAtMaturityByPartition", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [FullRedeemAtMaturityRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "fullRedeemAtMaturity", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetCouponHoldersRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getCouponHolders", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetTotalCouponHoldersRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getTotalCouponHolders", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CreateTrexSuiteBondRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "createTrexSuite", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [UpdateProceedRecipientDataRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "updateProceedRecipientData", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [RemoveProceedRecipientRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "removeProceedRecipient", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [AddProceedRecipientRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "addProceedRecipient", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetProceedRecipientsRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipients", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetProceedRecipientsCountRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipientsCount", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [GetProceedRecipientDataRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "getProceedRecipientData", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [IsProceedRecipientRequest]),
    __metadata("design:returntype", Promise)
], BondInPort.prototype, "isProceedRecipient", null);
const BondToken = new BondInPort();
export default BondToken;
