// SPDX-License-Identifier: Apache-2.0
import SetNetworkRequest from "../request/network/SetNetworkRequest";
import SetConfigurationRequest from "../request/management/SetConfigurationRequest";
import { createMock } from "@golevelup/ts-jest";
import LogService from "../../../app/service/log/LogService";
import ValidatedRequest from "../../../core/validation/ValidatedArgs";
import Network from "./Network";
import { SetConfigurationCommand } from "../../../app/usecase/command/network/setConfiguration/SetConfigurationCommand";
import { SetNetworkCommand } from "../../../app/usecase/command/network/setNetwork/SetNetworkCommand";
import { HederaIdPropsFixture } from "../../../../__tests__/fixtures/shared/DataFixture";
describe("Network", () => {
    let commandBusMock;
    let transactionServiceMock;
    let networkServiceMock;
    let setNetworkRequest;
    let setConfigurationRequest;
    let handleValidationSpy;
    const mockFactoryAddress = HederaIdPropsFixture.create().value;
    const mockResolverAddress = HederaIdPropsFixture.create().value;
    const mockEnvironment = "testnet";
    const mockMirrorNode = "mirror.node";
    const mockRpcNode = "rpc.node";
    const mockConsensusNodes = "consensus.nodes";
    beforeEach(() => {
        commandBusMock = createMock();
        transactionServiceMock = createMock();
        handleValidationSpy = jest.spyOn(ValidatedRequest, "handleValidation");
        networkServiceMock = createMock({
            configuration: {
                factoryAddress: mockFactoryAddress,
                resolverAddress: mockResolverAddress,
            },
            environment: mockEnvironment,
        });
        jest.spyOn(LogService, "logError").mockImplementation(() => { });
        setNetworkRequest = new SetNetworkRequest({
            environment: mockEnvironment,
            mirrorNode: mockMirrorNode,
            rpcNode: mockRpcNode,
            consensusNodes: mockConsensusNodes,
        });
        setConfigurationRequest = new SetConfigurationRequest({
            factoryAddress: mockFactoryAddress,
            resolverAddress: mockResolverAddress,
        });
        Network.commandBus = commandBusMock;
        Network.transactionService = transactionServiceMock;
        Network.networkService = networkServiceMock;
    });
    afterEach(() => {
        jest.resetAllMocks();
        jest.restoreAllMocks();
    });
    describe("setConfig", () => {
        it("should validate request and execute SetConfigurationCommand", async () => {
            const expectedResponse = {
                factoryAddress: mockFactoryAddress,
                resolverAddress: mockResolverAddress,
            };
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Network.setConfig(setConfigurationRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("SetConfigurationRequest", setConfigurationRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new SetConfigurationCommand(mockFactoryAddress, mockResolverAddress));
            expect(result).toEqual(expectedResponse);
        });
    });
    describe("getFactoryAddress", () => {
        it("should return factory address from networkService", async () => {
            const result = await Network.getFactoryAddress();
            expect(result).toBe(mockFactoryAddress);
        });
        it("should return empty string if configuration is undefined", async () => {
            networkServiceMock.configuration = undefined;
            const result = await Network.getFactoryAddress();
            expect(result).toBe("");
        });
    });
    describe("getResolverAddress", () => {
        it("should return resolver address from networkService", async () => {
            const result = await Network.getResolverAddress();
            expect(result).toBe(mockResolverAddress);
        });
        it("should return empty string if configuration is undefined", async () => {
            networkServiceMock.configuration = undefined;
            const result = await Network.getResolverAddress();
            expect(result).toBe("");
        });
    });
    describe("getNetwork", () => {
        it("should return environment from networkService", async () => {
            const result = await Network.getNetwork();
            expect(result).toBe(mockEnvironment);
        });
    });
    describe("isNetworkRecognized", () => {
        it("should return true if environment is recognized", async () => {
            const result = await Network.isNetworkRecognized();
            expect(result).toBe(true);
        });
        it("should return false if environment is unrecognized", async () => {
            networkServiceMock.environment = "unrecognized";
            const result = await Network.isNetworkRecognized();
            expect(result).toBe(false);
        });
    });
    describe("setNetwork", () => {
        it("should validate request and execute SetNetworkCommand", async () => {
            const expectedResponse = {
                environment: mockEnvironment,
                mirrorNode: mockMirrorNode,
                rpcNode: mockRpcNode,
                consensusNodes: mockConsensusNodes,
            };
            commandBusMock.execute.mockResolvedValue(expectedResponse);
            const result = await Network.setNetwork(setNetworkRequest);
            expect(handleValidationSpy).toHaveBeenCalledWith("SetNetworkRequest", setNetworkRequest);
            expect(commandBusMock.execute).toHaveBeenCalledWith(new SetNetworkCommand(mockEnvironment, mockMirrorNode, mockRpcNode, mockConsensusNodes));
            expect(result).toEqual(expectedResponse);
        });
    });
});
