"use strict";
// SPDX-License-Identifier: Apache-2.0
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FactoryOperations = void 0;
const ethers_1 = require("ethers");
const asset_tokenization_contracts_1 = require("@hashgraph/asset-tokenization-contracts");
const Constants_1 = require("../../../../core/Constants");
const FactorySecurityToken_1 = require("../../../../domain/context/factory/FactorySecurityToken");
const RegulationType_1 = require("../../../../domain/context/factory/RegulationType");
const SecurityRole_1 = require("../../../../domain/context/security/SecurityRole");
const BondDetailsData_1 = require("../../../../domain/context/factory/BondDetailsData");
const DividendType_1 = require("../../../../domain/context/equity/DividendType");
const MissingRegulationSubType_1 = require("../../../../domain/context/factory/error/MissingRegulationSubType");
const MissingRegulationType_1 = require("../../../../domain/context/factory/error/MissingRegulationType");
const SigningError_1 = require("../../../out/error/SigningError");
const LogService_1 = __importDefault(require("../../../../app/service/log/LogService"));
const InterestRate_1 = require("../../../../domain/context/bond/InterestRate");
const ImpactData_1 = require("../../../../domain/context/bond/ImpactData");
class FactoryOperations {
    executor;
    constructor(executor) {
        this.executor = executor;
    }
    async createEquity(securityInfo, equityInfo, factory, resolver, configId, configVersion, compliance, identityRegistryAddress, externalPauses, externalControlLists, externalKycLists, diamondOwnerAccount, factoryId) {
        try {
            if (!securityInfo.regulationType)
                throw new MissingRegulationType_1.MissingRegulationType();
            if (!securityInfo.regulationsubType)
                throw new MissingRegulationSubType_1.MissingRegulationSubType();
            const rbacAdmin = {
                role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
                members: [diamondOwnerAccount.toString()],
            };
            const erc20MetadataInfo = {
                name: securityInfo.name,
                symbol: securityInfo.symbol,
                isin: securityInfo.isin,
                decimals: securityInfo.decimals,
            };
            const resolverProxyConfiguration = {
                key: configId,
                version: configVersion,
            };
            const security = {
                arePartitionsProtected: securityInfo.arePartitionsProtected,
                isMultiPartition: securityInfo.isMultiPartition,
                resolver: resolver.toString(),
                resolverProxyConfiguration,
                rbacs: [rbacAdmin],
                isControllable: securityInfo.isControllable,
                isWhiteList: securityInfo.isWhiteList,
                maxSupply: securityInfo.maxSupply ? securityInfo.maxSupply.toString() : "0",
                erc20VotesActivated: securityInfo.erc20VotesActivated,
                erc20MetadataInfo,
                clearingActive: securityInfo.clearingActive,
                internalKycActivated: securityInfo.internalKycActivated,
                externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
                externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
                externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
                compliance: compliance.toString(),
                identityRegistry: identityRegistryAddress?.toString(),
            };
            const equityDetails = {
                votingRight: equityInfo.votingRight,
                informationRight: equityInfo.informationRight,
                liquidationRight: equityInfo.liquidationRight,
                subscriptionRight: equityInfo.subscriptionRight,
                conversionRight: equityInfo.conversionRight,
                redemptionRight: equityInfo.redemptionRight,
                putRight: equityInfo.putRight,
                dividendRight: DividendType_1.CastDividendType.toNumber(equityInfo.dividendRight),
                currency: equityInfo.currency,
                nominalValue: equityInfo.nominalValue.toString(),
                nominalValueDecimals: equityInfo.nominalValueDecimals,
            };
            const securityTokenToCreate = new FactorySecurityToken_1.FactoryEquityToken(security, equityDetails);
            const additionalSecurityData = {
                countriesControlListType: securityInfo.isCountryControlListWhiteList,
                listOfCountries: securityInfo.countries ?? "",
                info: securityInfo.info ?? "",
            };
            const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(securityInfo.regulationType), RegulationType_1.CastRegulationSubType.toNumber(securityInfo.regulationsubType), additionalSecurityData);
            LogService_1.default.logTrace(`Deploying equity: ${{ security: securityTokenToCreate }}`);
            return this.executor.executeContractCall(factoryId.toString(), asset_tokenization_contracts_1.Factory__factory.createInterface(), "deployEquity", [securityTokenToCreate, factoryRegulationData], Constants_1.GAS.CREATE_EQUITY_ST);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in HederaTransactionAdapter create operation : ${error}`);
        }
    }
    async createBond(securityInfo, bondInfo, factory, resolver, configId, configVersion, compliance, identityRegistry, externalPauses, externalControlLists, externalKycLists, diamondOwnerAccount, proceedRecipients = [], proceedRecipientsData = [], factoryId) {
        try {
            if (!securityInfo.regulationType)
                throw new MissingRegulationType_1.MissingRegulationType();
            if (!securityInfo.regulationsubType)
                throw new MissingRegulationSubType_1.MissingRegulationSubType();
            const rbacAdmin = {
                role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
                members: [diamondOwnerAccount.toString()],
            };
            const erc20MetadataInfo = {
                name: securityInfo.name,
                symbol: securityInfo.symbol,
                isin: securityInfo.isin,
                decimals: securityInfo.decimals,
            };
            const resolverProxyConfiguration = {
                key: configId,
                version: configVersion,
            };
            const security = {
                arePartitionsProtected: securityInfo.arePartitionsProtected,
                isMultiPartition: securityInfo.isMultiPartition,
                resolver: resolver.toString(),
                resolverProxyConfiguration,
                rbacs: [rbacAdmin],
                isControllable: securityInfo.isControllable,
                isWhiteList: securityInfo.isWhiteList,
                maxSupply: securityInfo.maxSupply ? securityInfo.maxSupply.toString() : "0",
                erc20VotesActivated: securityInfo.erc20VotesActivated,
                erc20MetadataInfo,
                clearingActive: securityInfo.clearingActive,
                internalKycActivated: securityInfo.internalKycActivated,
                externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
                externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
                externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
                compliance: compliance.toString(),
                identityRegistry: identityRegistry.toString(),
            };
            const bondDetails = new BondDetailsData_1.BondDetailsData(bondInfo.currency, bondInfo.nominalValue.toString(), bondInfo.nominalValueDecimals, bondInfo.startingDate.toString(), bondInfo.maturityDate.toString());
            const securityTokenToCreate = new FactorySecurityToken_1.FactoryBondToken(security, bondDetails, proceedRecipients.map((addr) => addr.toString()), proceedRecipientsData.map((data) => (data == "" ? "0x" : data)));
            const additionalSecurityData = {
                countriesControlListType: securityInfo.isCountryControlListWhiteList,
                listOfCountries: securityInfo.countries ?? "",
                info: securityInfo.info ?? "",
            };
            const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(securityInfo.regulationType), RegulationType_1.CastRegulationSubType.toNumber(securityInfo.regulationsubType), additionalSecurityData);
            LogService_1.default.logTrace(`Deploying bond: ${{ security: securityTokenToCreate }}`);
            return this.executor.executeContractCall(factoryId.toString(), asset_tokenization_contracts_1.Factory__factory.createInterface(), "deployBond", [securityTokenToCreate, factoryRegulationData], Constants_1.GAS.CREATE_BOND_ST);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in HederaTransactionAdapter create operation : ${error}`);
        }
    }
    async createBondFixedRate(securityInfo, bondInfo, factory, resolver, configId, configVersion, compliance, identityRegistry, externalPauses, externalControlLists, externalKycLists, diamondOwnerAccount, proceedRecipients = [], proceedRecipientsData = [], factoryId) {
        try {
            if (!securityInfo.regulationType)
                throw new MissingRegulationType_1.MissingRegulationType();
            if (!securityInfo.regulationsubType)
                throw new MissingRegulationSubType_1.MissingRegulationSubType();
            const rbacAdmin = {
                role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
                members: [diamondOwnerAccount.toString()],
            };
            const erc20MetadataInfo = {
                name: securityInfo.name,
                symbol: securityInfo.symbol,
                isin: securityInfo.isin,
                decimals: securityInfo.decimals,
            };
            const resolverProxyConfiguration = {
                key: configId,
                version: configVersion,
            };
            const security = {
                arePartitionsProtected: securityInfo.arePartitionsProtected,
                isMultiPartition: securityInfo.isMultiPartition,
                resolver: resolver.toString(),
                resolverProxyConfiguration,
                rbacs: [rbacAdmin],
                isControllable: securityInfo.isControllable,
                isWhiteList: securityInfo.isWhiteList,
                maxSupply: securityInfo.maxSupply ? securityInfo.maxSupply.toString() : "0",
                erc20VotesActivated: securityInfo.erc20VotesActivated,
                erc20MetadataInfo,
                clearingActive: securityInfo.clearingActive,
                internalKycActivated: securityInfo.internalKycActivated,
                externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
                externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
                externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
                compliance: compliance.toString(),
                identityRegistry: identityRegistry.toString(),
            };
            const bondDetails = new BondDetailsData_1.BondDetailsData(bondInfo.currency, bondInfo.nominalValue.toString(), bondInfo.nominalValueDecimals, bondInfo.startingDate.toString(), bondInfo.maturityDate.toString());
            const securityTokenToCreate = new FactorySecurityToken_1.FactoryBondToken(security, bondDetails, proceedRecipients.map((addr) => addr.toString()), proceedRecipientsData.map((data) => (data == "" ? "0x" : data)));
            const additionalSecurityData = {
                countriesControlListType: securityInfo.isCountryControlListWhiteList,
                listOfCountries: securityInfo.countries ?? "",
                info: securityInfo.info ?? "",
            };
            const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(securityInfo.regulationType), RegulationType_1.CastRegulationSubType.toNumber(securityInfo.regulationsubType), additionalSecurityData);
            const bondFixedRateData = {
                bondData: securityTokenToCreate,
                factoryRegulationData: factoryRegulationData,
                fixedRateData: { rate: bondInfo.rate, rateDecimals: bondInfo.rateDecimals },
            };
            LogService_1.default.logTrace(`Deploying bond fixed rate: ${{ security: securityTokenToCreate }}`);
            return this.executor.executeContractCall(factoryId.toString(), asset_tokenization_contracts_1.Factory__factory.createInterface(), "deployBondFixedRate", [bondFixedRateData], Constants_1.GAS.CREATE_BOND_ST);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in HederaTransactionAdapter create operation : ${error}`);
        }
    }
    async createBondKpiLinkedRate(securityInfo, bondInfo, factory, resolver, configId, configVersion, compliance, identityRegistry, externalPauses, externalControlLists, externalKycLists, diamondOwnerAccount, proceedRecipients = [], proceedRecipientsData = [], factoryId) {
        try {
            if (!securityInfo.regulationType)
                throw new MissingRegulationType_1.MissingRegulationType();
            if (!securityInfo.regulationsubType)
                throw new MissingRegulationSubType_1.MissingRegulationSubType();
            const rbacAdmin = {
                role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
                members: [diamondOwnerAccount.toString()],
            };
            const erc20MetadataInfo = {
                name: securityInfo.name,
                symbol: securityInfo.symbol,
                isin: securityInfo.isin,
                decimals: securityInfo.decimals,
            };
            const resolverProxyConfiguration = {
                key: configId,
                version: configVersion,
            };
            const security = {
                arePartitionsProtected: securityInfo.arePartitionsProtected,
                isMultiPartition: securityInfo.isMultiPartition,
                resolver: resolver.toString(),
                resolverProxyConfiguration,
                rbacs: [rbacAdmin],
                isControllable: securityInfo.isControllable,
                isWhiteList: securityInfo.isWhiteList,
                maxSupply: securityInfo.maxSupply ? securityInfo.maxSupply.toString() : "0",
                erc20VotesActivated: securityInfo.erc20VotesActivated,
                erc20MetadataInfo,
                clearingActive: securityInfo.clearingActive,
                internalKycActivated: securityInfo.internalKycActivated,
                externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
                externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
                externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
                compliance: compliance.toString(),
                identityRegistry: identityRegistry.toString(),
            };
            const bondDetails = new BondDetailsData_1.BondDetailsData(bondInfo.currency, bondInfo.nominalValue.toString(), bondInfo.nominalValueDecimals, bondInfo.startingDate.toString(), bondInfo.maturityDate.toString());
            const securityTokenToCreate = new FactorySecurityToken_1.FactoryBondToken(security, bondDetails, proceedRecipients.map((addr) => addr.toString()), proceedRecipientsData.map((data) => (data == "" ? "0x" : data)));
            const additionalSecurityData = {
                countriesControlListType: securityInfo.isCountryControlListWhiteList,
                listOfCountries: securityInfo.countries ?? "",
                info: securityInfo.info ?? "",
            };
            const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(securityInfo.regulationType), RegulationType_1.CastRegulationSubType.toNumber(securityInfo.regulationsubType), additionalSecurityData);
            const interestRate = new InterestRate_1.InterestRate(bondInfo.interestRate.maxRate, bondInfo.interestRate.baseRate, bondInfo.interestRate.minRate, bondInfo.interestRate.startPeriod, bondInfo.interestRate.startRate, bondInfo.interestRate.missedPenalty, bondInfo.interestRate.reportPeriod, bondInfo.interestRate.rateDecimals);
            const impactData = new ImpactData_1.ImpactData(bondInfo.impactData.maxDeviationCap, bondInfo.impactData.baseLine, bondInfo.impactData.maxDeviationFloor, bondInfo.impactData.impactDataDecimals, bondInfo.impactData.adjustmentPrecision);
            const bondKpiLinkedRateData = {
                bondData: securityTokenToCreate,
                factoryRegulationData: factoryRegulationData,
                interestRate: interestRate,
                impactData: impactData,
                kpiOracle: Constants_1.EVM_ZERO_ADDRESS,
            };
            LogService_1.default.logTrace(`Deploying bond kpi linked rate: ${{ security: securityTokenToCreate }}`);
            return this.executor.executeContractCall(factoryId.toString(), asset_tokenization_contracts_1.Factory__factory.createInterface(), "deployBondKpiLinkedRate", [bondKpiLinkedRateData], Constants_1.GAS.CREATE_BOND_ST);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in HederaTransactionAdapter create operation : ${error}`);
        }
    }
    async createTrexSuiteBond(salt, owner, irs, onchainId, irAgents, tokenAgents, compliancesModules, complianceSettings, claimTopics, issuers, issuerClaims, security, bondDetails, factory, resolver, configId, configVersion, compliance, identityRegistryAddress, diamondOwnerAccount, proceedRecipients = [], proceedRecipientsData = [], externalPauses, externalControlLists, externalKycLists, factoryId) {
        LogService_1.default.logTrace(`Deploying trex suite bond: ${security.toString()}`);
        if (!security.regulationType)
            throw new MissingRegulationType_1.MissingRegulationType();
        if (!security.regulationsubType)
            throw new MissingRegulationSubType_1.MissingRegulationSubType();
        const rbacAdmin = {
            role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
            members: [diamondOwnerAccount.toString()],
        };
        const erc20MetadataInfo = {
            name: security.name,
            symbol: security.symbol,
            isin: security.isin,
            decimals: security.decimals,
        };
        const resolverProxyConfiguration = {
            key: configId,
            version: configVersion,
        };
        const securityData = {
            arePartitionsProtected: security.arePartitionsProtected,
            isMultiPartition: security.isMultiPartition,
            resolver: resolver.toString(),
            resolverProxyConfiguration,
            rbacs: [rbacAdmin],
            isControllable: security.isControllable,
            isWhiteList: security.isWhiteList,
            maxSupply: security.maxSupply ? security.maxSupply.toString() : "0",
            erc20MetadataInfo,
            clearingActive: security.clearingActive,
            internalKycActivated: security.internalKycActivated,
            externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
            externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
            externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
            compliance: compliance.toString(),
            identityRegistry: identityRegistryAddress.toString(),
            erc20VotesActivated: security.erc20VotesActivated,
        };
        const bondDetailsData = new BondDetailsData_1.BondDetailsData(bondDetails.currency, bondDetails.nominalValue.toString(), bondDetails.nominalValueDecimals, bondDetails.startingDate.toString(), bondDetails.maturityDate.toString());
        const securityTokenToCreate = new FactorySecurityToken_1.FactoryBondToken(securityData, bondDetailsData, proceedRecipients.map((b) => b.toString()), proceedRecipientsData.map((data) => (data == "" ? "0x" : data)));
        const additionalSecurityData = {
            countriesControlListType: security.isCountryControlListWhiteList,
            listOfCountries: security.countries ?? "",
            info: security.info ?? "",
        };
        const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(security.regulationType), RegulationType_1.CastRegulationSubType.toNumber(security.regulationsubType), additionalSecurityData);
        try {
            return this.executor.executeContractCall(factoryId.toString(), new ethers_1.ethers.Interface(asset_tokenization_contracts_1.TREXFactoryAts__factory.abi), "deployTREXSuiteAtsBond", [
                salt,
                {
                    owner,
                    irs,
                    ONCHAINID: onchainId,
                    irAgents,
                    tokenAgents,
                    complianceModules: compliancesModules,
                    complianceSettings,
                },
                { claimTopics, issuers, issuerClaims },
                securityTokenToCreate,
                factoryRegulationData,
            ], Constants_1.GAS.TREX_CREATE_SUITE);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in TREXFactoryAts__factory deploy operation : ${error}`);
        }
    }
    async createTrexSuiteEquity(salt, owner, irs, onchainId, irAgents, tokenAgents, compliancesModules, complianceSettings, claimTopics, issuers, issuerClaims, security, equityDetails, factory, resolver, configId, configVersion, compliance, identityRegistryAddress, diamondOwnerAccount, externalPauses, externalControlLists, externalKycLists, factoryId) {
        LogService_1.default.logTrace(`Deploying trex suite equity: ${security.toString()}`);
        try {
            if (!security.regulationType)
                throw new MissingRegulationType_1.MissingRegulationType();
            if (!security.regulationsubType)
                throw new MissingRegulationSubType_1.MissingRegulationSubType();
            const rbacAdmin = {
                role: SecurityRole_1.SecurityRole._DEFAULT_ADMIN_ROLE,
                members: [diamondOwnerAccount.toString()],
            };
            const erc20MetadataInfo = {
                name: security.name,
                symbol: security.symbol,
                isin: security.isin,
                decimals: security.decimals,
            };
            const resolverProxyConfiguration = {
                key: configId,
                version: configVersion,
            };
            const securityData = {
                arePartitionsProtected: security.arePartitionsProtected,
                isMultiPartition: security.isMultiPartition,
                resolver: resolver.toString(),
                resolverProxyConfiguration,
                rbacs: [rbacAdmin],
                isControllable: security.isControllable,
                isWhiteList: security.isWhiteList,
                maxSupply: security.maxSupply ? security.maxSupply.toString() : "0",
                erc20MetadataInfo,
                clearingActive: security.clearingActive,
                internalKycActivated: security.internalKycActivated,
                externalPauses: externalPauses?.map((address) => address.toString()) ?? [],
                externalControlLists: externalControlLists?.map((address) => address.toString()) ?? [],
                externalKycLists: externalKycLists?.map((address) => address.toString()) ?? [],
                compliance: compliance.toString(),
                identityRegistry: identityRegistryAddress?.toString(),
                erc20VotesActivated: security.erc20VotesActivated,
            };
            const equityDetailsData = {
                votingRight: equityDetails.votingRight,
                informationRight: equityDetails.informationRight,
                liquidationRight: equityDetails.liquidationRight,
                subscriptionRight: equityDetails.subscriptionRight,
                conversionRight: equityDetails.conversionRight,
                redemptionRight: equityDetails.redemptionRight,
                putRight: equityDetails.putRight,
                dividendRight: DividendType_1.CastDividendType.toNumber(equityDetails.dividendRight),
                currency: equityDetails.currency,
                nominalValue: equityDetails.nominalValue.toString(),
                nominalValueDecimals: equityDetails.nominalValueDecimals,
            };
            const securityTokenToCreate = new FactorySecurityToken_1.FactoryEquityToken(securityData, equityDetailsData);
            const additionalSecurityData = {
                countriesControlListType: security.isCountryControlListWhiteList,
                listOfCountries: security.countries ?? "",
                info: security.info ?? "",
            };
            const factoryRegulationData = new FactorySecurityToken_1.FactoryRegulationData(RegulationType_1.CastRegulationType.toNumber(security.regulationType), RegulationType_1.CastRegulationSubType.toNumber(security.regulationsubType), additionalSecurityData);
            LogService_1.default.logTrace(`Deploying equity: ${{ security: securityTokenToCreate }}`);
            return this.executor.executeContractCall(factoryId.toString(), new ethers_1.ethers.Interface(asset_tokenization_contracts_1.TREXFactoryAts__factory.abi), "deployTREXSuiteAtsEquity", [
                salt,
                {
                    owner,
                    irs,
                    ONCHAINID: onchainId,
                    irAgents,
                    tokenAgents,
                    complianceModules: compliancesModules,
                    complianceSettings,
                },
                { claimTopics, issuers, issuerClaims },
                securityTokenToCreate,
                factoryRegulationData,
            ], Constants_1.GAS.TREX_CREATE_SUITE);
        }
        catch (error) {
            LogService_1.default.logError(error);
            throw new SigningError_1.SigningError(`Unexpected error in HederaTransactionAdapter create operation : ${error}`);
        }
    }
}
exports.FactoryOperations = FactoryOperations;
