// 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);
};
/* eslint-disable @typescript-eslint/no-unused-vars */
import Injectable from "../../../core/injectable/Injectable";
import { CommandBus } from "../../../core/command/CommandBus";
import { ConnectCommand } from "../../../app/usecase/command/network/connect/ConnectCommand";
import ConnectRequest, { SupportedWallets, } from "../request/network/ConnectRequest";
import RequestMapper from "../request/mapping/RequestMapper";
import TransactionService from "../../../app/service/transaction/TransactionService";
import NetworkService from "../../../app/service/network/NetworkService";
import SetNetworkRequest from "../request/network/SetNetworkRequest";
import { SetNetworkCommand } from "../../../app/usecase/command/network/setNetwork/SetNetworkCommand";
import { SetConfigurationCommand } from "../../../app/usecase/command/network/setConfiguration/SetConfigurationCommand";
import { unrecognized } from "../../../domain/context/network/Environment";
import InitializationRequest from "../request/network/InitializationRequest";
import Event from "../event/Event";
import { RPCTransactionAdapter } from "../../out/rpc/RPCTransactionAdapter";
import { LogError } from "../../../core/decorator/LogErrorDecorator";
import SetConfigurationRequest from "../request/management/SetConfigurationRequest";
import ValidatedRequest from "../../../core/validation/ValidatedArgs";
import { HederaWalletConnectTransactionAdapter } from "../../out/hs/walletconnect/HederaWalletConnectTransactionAdapter";
import { DFNSTransactionAdapter } from "../../out/hs/custodial/DFNSTransactionAdapter";
import { FireblocksTransactionAdapter } from "../../out/hs/custodial/FireblocksTransactionAdapter";
import { AWSKMSTransactionAdapter } from "../../out/hs/custodial/AWSKMSTransactionAdapter";
import LogService from "../../../app/service/log/LogService";
export { SupportedWallets };
class NetworkInPort {
    commandBus;
    transactionService;
    networkService;
    constructor(commandBus = Injectable.resolve(CommandBus), transactionService = Injectable.resolve(TransactionService), networkService = Injectable.resolve(NetworkService)) {
        this.commandBus = commandBus;
        this.transactionService = transactionService;
        this.networkService = networkService;
    }
    async setConfig(req) {
        ValidatedRequest.handleValidation("SetConfigurationRequest", req);
        const res = await this.commandBus.execute(new SetConfigurationCommand(req.factoryAddress, req.resolverAddress));
        return res;
    }
    getFactoryAddress() {
        return this.networkService.configuration ? this.networkService.configuration.factoryAddress : "";
    }
    getResolverAddress() {
        return this.networkService.configuration ? this.networkService.configuration.resolverAddress : "";
    }
    getNetwork() {
        return this.networkService.environment;
    }
    isNetworkRecognized() {
        return this.networkService.environment != unrecognized;
    }
    async setNetwork(req) {
        ValidatedRequest.handleValidation("SetNetworkRequest", req);
        const res = await this.commandBus.execute(new SetNetworkCommand(req.environment, req.mirrorNode, req.rpcNode, req.consensusNodes));
        return res;
    }
    async init(req) {
        ValidatedRequest.handleValidation("InitializationRequest", req);
        await this.setNetwork(new SetNetworkRequest({
            environment: req.network,
            mirrorNode: req.mirrorNode,
            rpcNode: req.rpcNode,
        }));
        if (req.configuration)
            if (req.configuration.factoryAddress && req.configuration.resolverAddress)
                await this.setConfig(new SetConfigurationRequest({
                    factoryAddress: req.configuration.factoryAddress,
                    resolverAddress: req.configuration.resolverAddress,
                }));
        req.events && Event.register(req.events);
        const wallets = [];
        const instances = Injectable.registerTransactionAdapterInstances();
        for (const val of instances) {
            if (val instanceof RPCTransactionAdapter) {
                wallets.push(SupportedWallets.METAMASK);
            }
            else if (val instanceof HederaWalletConnectTransactionAdapter) {
                wallets.push(SupportedWallets.HWALLETCONNECT);
            }
            else if (val instanceof DFNSTransactionAdapter) {
                wallets.push(SupportedWallets.DFNS);
            }
            else if (val instanceof FireblocksTransactionAdapter) {
                wallets.push(SupportedWallets.FIREBLOCKS);
            }
            else if (val instanceof AWSKMSTransactionAdapter) {
                wallets.push(SupportedWallets.AWSKMS);
            }
            await val.init();
            if (val instanceof RPCTransactionAdapter) {
                val.setConfig({
                    mirrorNodes: req.mirrorNodes,
                    jsonRpcRelays: req.jsonRpcRelays,
                    factories: req.factories,
                    resolvers: req.resolvers,
                });
            }
        }
        return wallets;
    }
    async connect(req) {
        LogService.logInfo("ConnectRequest from network", req);
        ValidatedRequest.handleValidation("ConnectRequest", req);
        const account = req.account ? RequestMapper.mapAccount(req.account) : undefined;
        const debug = req.debug ?? false;
        const hwcSettings = req.hwcSettings ? RequestMapper.hwcRequestToHWCSettings(req.hwcSettings) : undefined;
        const custodialSettings = this.getCustodialSettings(req);
        LogService.logTrace("SetNetworkCommand", req.network, req.mirrorNode, req.rpcNode);
        await this.commandBus.execute(new SetNetworkCommand(req.network, req.mirrorNode, req.rpcNode));
        LogService.logTrace("ConnectRequest", req.wallet, account, hwcSettings, debug, custodialSettings);
        const res = await this.commandBus.execute(new ConnectCommand(req.network, req.wallet, account, hwcSettings, debug, custodialSettings));
        return res.payload;
    }
    getCustodialSettings(req) {
        if (!req.custodialWalletSettings) {
            return undefined;
        }
        switch (req.wallet) {
            case SupportedWallets.DFNS:
                return RequestMapper.dfnsRequestToDfnsSettings(req.custodialWalletSettings);
            case SupportedWallets.FIREBLOCKS:
                return RequestMapper.fireblocksRequestToFireblocksSettings(req.custodialWalletSettings);
            case SupportedWallets.AWSKMS:
                return RequestMapper.awsKmsRequestToAwsKmsSettings(req.custodialWalletSettings);
            default:
                return undefined;
        }
    }
    disconnect() {
        return this.transactionService.getHandler().stop();
    }
}
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [SetConfigurationRequest]),
    __metadata("design:returntype", Promise)
], NetworkInPort.prototype, "setConfig", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", String)
], NetworkInPort.prototype, "getFactoryAddress", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", String)
], NetworkInPort.prototype, "getResolverAddress", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", String)
], NetworkInPort.prototype, "getNetwork", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Boolean)
], NetworkInPort.prototype, "isNetworkRecognized", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [SetNetworkRequest]),
    __metadata("design:returntype", Promise)
], NetworkInPort.prototype, "setNetwork", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [InitializationRequest]),
    __metadata("design:returntype", Promise)
], NetworkInPort.prototype, "init", null);
__decorate([
    LogError,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ConnectRequest]),
    __metadata("design:returntype", Promise)
], NetworkInPort.prototype, "connect", null);
const Network = new NetworkInPort();
export default Network;
