/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { TypedEventEmitter } from "@fluid-internal/client-utils";
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { expect } from "chai";
import { spy } from "sinon";
import { IFluidContainerSystemEventNames, } from "../container/index.js";
import { startTelemetry } from "../factory/index.js";
import { AppInsightsTelemetryConsumer, ContainerTelemetryEventNames, } from "../index.js";
/**
 * For these unit tests, we are just interested in the event emitter part of the Fluid container.
 * The rest of the functionality of IFluidContainer is irrelevant.
 */
class MockFluidContainer extends TypedEventEmitter {
    connect() {
        this.emit(IFluidContainerSystemEventNames.CONNECTED);
    }
    disconnect() {
        this.emit(IFluidContainerSystemEventNames.DISCONNECTED);
    }
    dispose(error) {
        this.emit(IFluidContainerSystemEventNames.DISPOSED, error);
    }
}
describe("container telemetry via", () => {
    let mockFluidContainer;
    const mockContainerId = "mockContainerId";
    let appInsightsClient;
    let trackEventSpy;
    let telemetryConfig;
    beforeEach(() => {
        appInsightsClient = new ApplicationInsights({
            config: {
                connectionString: 
                // (this is an example string)
                "InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/",
            },
        });
        trackEventSpy = spy(appInsightsClient, "trackEvent");
        mockFluidContainer = new MockFluidContainer();
        telemetryConfig = {
            container: mockFluidContainer,
            containerId: mockContainerId,
            consumers: [new AppInsightsTelemetryConsumer(appInsightsClient)],
        };
    });
    it("Emitting 'connected' container system event produces expected ContainerConnectedTelemetry using Azure App Insights", () => {
        startTelemetry(telemetryConfig);
        mockFluidContainer.connect();
        expect(trackEventSpy.callCount).to.equal(1);
        // Obtain the events from the method that the spy was called with
        const actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0];
        const actualContainerTelemetry = actualAppInsightsTelemetry.properties;
        const expectedAppInsightsTelemetry = {
            name: ContainerTelemetryEventNames.CONNECTED,
            properties: {
                eventName: ContainerTelemetryEventNames.CONNECTED,
                containerId: mockContainerId,
                containerInstanceId: actualContainerTelemetry.containerInstanceId,
            },
        };
        expect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);
        // We won't know what the container containerInstanceId will be but we can still check that it is defined.
        expect(actualContainerTelemetry.containerInstanceId)
            .to.be.a("string")
            .with.length.above(0);
    });
    it("Emitting 'disconnected' container system event produces expected ContainerDisconnectedTelemetry using Azure App Insights", () => {
        startTelemetry(telemetryConfig);
        mockFluidContainer.disconnect();
        expect(trackEventSpy.callCount).to.equal(1);
        // Obtain the events from the method that the spy was called with
        const actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0];
        const actualContainerTelemetry = actualAppInsightsTelemetry.properties;
        const expectedAppInsightsTelemetry = {
            name: ContainerTelemetryEventNames.DISCONNECTED,
            properties: {
                eventName: ContainerTelemetryEventNames.DISCONNECTED,
                containerId: mockContainerId,
                containerInstanceId: actualContainerTelemetry.containerInstanceId,
            },
        };
        expect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);
        // We won't know what the container containerInstanceId will be but we can still check that it is defined.
        expect(actualContainerTelemetry.containerInstanceId)
            .to.be.a("string")
            .with.length.above(0);
    });
    it("Emitting 'disposed' system event produces expected ContainerDisposedTelemetry using Azure App Insights", () => {
        startTelemetry(telemetryConfig);
        mockFluidContainer.dispose();
        expect(trackEventSpy.callCount).to.equal(1);
        // Obtain the events from the method that the spy was called with
        const actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0];
        const actualContainerTelemetry = actualAppInsightsTelemetry.properties;
        const expectedAppInsightsTelemetry = {
            name: ContainerTelemetryEventNames.DISPOSED,
            properties: {
                eventName: ContainerTelemetryEventNames.DISPOSED,
                containerId: mockContainerId,
                containerInstanceId: actualContainerTelemetry.containerInstanceId,
            },
        };
        expect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);
        // We won't know what the container containerInstanceId will be but we can still check that it is defined.
        expect(actualContainerTelemetry.containerInstanceId)
            .to.be.a("string")
            .with.length.above(0);
    });
    it("Emitting 'disposed' system event with an error produces expected ContainerDisposedTelemetry using Azure App Insights", () => {
        startTelemetry(telemetryConfig);
        const containerError = {
            errorType: "unknown error",
            message: "An unknown error occured",
            stack: "example stack error at line 52 of Container.ts",
        };
        mockFluidContainer.dispose(containerError);
        // Obtain the events from the method that the spy was called with
        const actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0];
        const actualContainerTelemetry = actualAppInsightsTelemetry.properties;
        const expectedAppInsightsTelemetry = {
            name: ContainerTelemetryEventNames.DISPOSED,
            properties: {
                eventName: ContainerTelemetryEventNames.DISPOSED,
                containerId: mockContainerId,
                containerInstanceId: actualContainerTelemetry.containerInstanceId,
                error: containerError,
            },
        };
        expect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);
        // We won't know what the container containerInstanceId will be but we can still check that it is defined.
        expect(actualContainerTelemetry.containerInstanceId)
            .to.be.a("string")
            .with.length.above(0);
    });
});
//# sourceMappingURL=containerTelemetry.spec.js.map