// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { loadConfigSync } from "@typeagent/config";
loadConfigSync();

import {
    createSchemaInfoProvider,
    getCacheFactory,
    readExplanationTestData,
    getAllActionConfigProvider,
} from "agent-dispatcher/internal";
import {
    fromJsonActions,
    normalizeParamString,
    RequestAction,
} from "agent-cache";
import { getDefaultAppAgentProviders } from "../src/defaultAgentProviders.js";
import { glob } from "glob";

const dataFiles = ["test/data/explanations/**/v5/*.json"];

const inputs = await Promise.all(
    (await glob(dataFiles)).map((f) => readExplanationTestData(f)),
);

const testInput = inputs.flatMap((f) =>
    f.entries.map<[string, string, RequestAction, object, string[]]>((data) => [
        f.schemaName,
        f.explainerName,
        new RequestAction(data.request, fromJsonActions(data.action)),
        data.explanation,
        data.tags ?? [],
    ]),
);

const matchConfig = {
    enableWildcard: false,
    enableEntityWildcard: false,
    rejectReferences: false,
    partial: false,
};

const schemaInfoProvider = createSchemaInfoProvider(
    (await getAllActionConfigProvider(getDefaultAppAgentProviders(undefined)))
        .provider,
);

describe("construction", () => {
    describe("roundtrip", () => {
        it.each(testInput)(
            "[%s %s] '%s'",
            async (
                schemaName,
                explainerName,
                requestAction,
                explanation,
                tags,
            ) => {
                const explainer = getCacheFactory().getExplainer(
                    [schemaName],
                    explainerName,
                );

                const construction = explainer.createConstruction!(
                    requestAction,
                    explanation,
                    {
                        schemaInfoProvider,
                    },
                );

                const matched = construction.match(
                    requestAction.request,
                    matchConfig,
                );

                const matchedLowerCase = construction.match(
                    normalizeParamString(requestAction.request),
                    matchConfig,
                );
                if (!tags.includes("failedRoundTripAction")) {
                    // Able to match roundtrip
                    expect(matched.length).not.toEqual(0);
                    expect(matched[0].match).toEqual(requestAction);

                    expect(matchedLowerCase.length).not.toEqual(0);
                    // Lower-case match finds the right action but string parameter
                    // values are also lowercased, so we only verify the action name.
                    expect(
                        matchedLowerCase[0].match.actions[0].action.actionName,
                    ).toEqual(requestAction.actions[0].action.actionName);
                } else {
                    // TODO: needs fix these
                    if (matched.length !== 0) {
                        expect(matched[0].match).not.toEqual(requestAction);
                    }
                }
            },
        );
    });
});
