import { jsx as _jsx } from "react/jsx-runtime";
/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { render, waitFor, fireEvent, findByText, getByText, getByDisplayValue, findByDisplayValue, getByRole, } from '@testing-library/react';
import { LogService, guaranteeNonNullable } from '@finos/legend-shared';
import { createSpy } from '@finos/legend-shared/test';
import { GraphManagerState, PackageableElementExplicitReference, RuntimePointer, Core_GraphManagerPreset, } from '@finos/legend-graph';
import { ApplicationStoreProvider, ApplicationFrameworkProvider, ApplicationStore, } from '@finos/legend-application';
import { TEST__BrowserEnvironmentProvider } from '@finos/legend-application/test';
import { QueryBuilder } from '../QueryBuilder.js';
import { INTERNAL__BasicQueryBuilderState, } from '../../stores/QueryBuilderState.js';
import { QueryBuilder_GraphManagerPreset } from '../../graph-manager/QueryBuilder_GraphManagerPreset.js';
import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
import { TEST__LegendApplicationPluginManager, TEST__getGenericApplicationConfig, } from '../../stores/__test-utils__/QueryBuilderStateTestUtils.js';
import { STYLE_PREFIX, STYLE_PREFIX__DARK } from '@finos/legend-art';
import { expect } from '@jest/globals';
import { QueryBuilderActionConfig, QueryBuilderAdvancedWorkflowState, } from '../../stores/query-workflow/QueryBuilderWorkFlowState.js';
import { AccessorQueryBuilderState } from '../../stores/workflows/accessor/AccessorQueryBuilderState.js';
import { Route, Routes } from '@finos/legend-application/browser';
import { BasicValueSpecificationEditor, } from '../shared/BasicValueSpecificationEditor.js';
import { V1_BasicValueSpecificationEditor, } from '../shared/V1_BasicValueSpecificationEditor.js';
const getSelectorContainerClassName = (lightMode) => '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__value-container`;
const getSelectorInputClassName = (lightMode) => '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__single-value`;
export const selectFromCustomSelectorInput = (selectorContainer, optionText, lightMode) => {
    const selectorContainerClassName = getSelectorContainerClassName(lightMode);
    const selectorInputValue = getSelectorInputClassName(lightMode);
    let foundOptionText = false;
    const selector = selectorContainer.querySelector(selectorContainerClassName);
    // be careful that the first option in the dropdown has been selected
    fireEvent.keyDown(selector, { key: 'ArrowDown' });
    fireEvent.keyDown(selector, { key: 'Enter' });
    expect(selector.querySelector(selectorInputValue)).not.toBeNull();
    const firstOptionValue = guaranteeNonNullable(selector.querySelector(selectorInputValue)).textContent;
    let currentOptionValue = firstOptionValue;
    let numofPress = 1;
    // Since the selector value can't be directly changed to the desired option value through fireEvent.change(),
    // we need to repeatedly press the ArrowDown key to select it. However, each time we restart this process,
    // it starts from the beginning of the dropdown list, creating a circular pattern.
    // To prevent a loop, we must keep track of the number of times we press the key to select other options
    // and ensure we don't return to the initial option.
    while ((!foundOptionText && currentOptionValue !== firstOptionValue) ||
        numofPress === 1) {
        for (let i = 0; i < numofPress + 1; i++) {
            fireEvent.keyDown(selector, { key: 'ArrowDown' });
        }
        fireEvent.keyDown(selector, { key: 'Enter' });
        expect(selector.querySelector(selectorInputValue)).not.toBeNull();
        currentOptionValue = guaranteeNonNullable(selector.querySelector(selectorInputValue)).textContent;
        if (currentOptionValue === optionText) {
            foundOptionText = true;
        }
        numofPress++;
    }
    if (!foundOptionText) {
        throw new Error(`The option is unavailable in the selector dropdown. Kindly review the input: ${optionText}`);
    }
};
export const selectFirstOptionFromCustomSelectorInput = (selectorContainer, lightMode, verifyInputValue) => {
    const selectorContainerClassName = getSelectorContainerClassName(lightMode);
    const selectorInputValue = getSelectorInputClassName(lightMode);
    const selector = selectorContainer.querySelector(selectorContainerClassName);
    fireEvent.keyDown(selector, { key: 'ArrowDown' });
    fireEvent.keyDown(selector, { key: 'Enter' });
    if (verifyInputValue ?? true) {
        expect(selector.querySelector(selectorInputValue)).not.toBeNull();
    }
};
export const getCustomSelectorInputValue = (selectorContainer, lightMode) => {
    const selectorContainerClassName = getSelectorContainerClassName(lightMode);
    const selectorInputValue = getSelectorInputClassName(lightMode);
    const selector = guaranteeNonNullable(selectorContainer.querySelector(selectorContainerClassName));
    const selectorInput = guaranteeNonNullable(selector.querySelector(selectorInputValue));
    return selectorInput.textContent;
};
export const dragAndDrop = async (source, drop, panel, draggingHoverText) => {
    fireEvent.dragStart(source);
    fireEvent.dragEnter(drop);
    fireEvent.dragOver(drop);
    if (draggingHoverText) {
        await findByText(panel, draggingHoverText);
        fireEvent.drop(getByText(panel, draggingHoverText));
    }
    else {
        fireEvent.dragOver(drop);
    }
};
export const setDerivedPropertyValue = async (derivedPropertyButton, value, renderResult, options) => {
    fireEvent.click(derivedPropertyButton);
    const dpModal = await renderResult.findByRole('dialog');
    await findByText(dpModal, 'Derived Property');
    fireEvent.change(getByDisplayValue(dpModal, options?.currentDisplayValue ?? ''), {
        target: { value },
    });
    await findByDisplayValue(dpModal, value);
    fireEvent.click(getByRole(dpModal, 'button', { name: 'Done' }));
    await waitFor(() => expect(renderResult.queryByRole('dialog')).toBeNull());
};
export const TEST__setUpGraphManagerState = async (entities, pluginManager) => {
    pluginManager.usePresets([new QueryBuilder_GraphManagerPreset()]).install();
    const graphManagerState = new GraphManagerState(pluginManager, new LogService());
    await graphManagerState.graphManager.initialize({
        env: 'test',
        tabSize: 2,
        clientConfig: {},
    });
    await graphManagerState.initializeSystem();
    await graphManagerState.graphManager.buildGraph(graphManagerState.graph, entities, graphManagerState.graphBuildState);
    return graphManagerState;
};
export const TEST__setUpQueryBuilder = async (entities, lambda, mappingPath, runtimePath, rawMappingModelCoverageAnalysisResult) => {
    const pluginManager = TEST__LegendApplicationPluginManager.create();
    const graphManagerState = await TEST__setUpGraphManagerState(entities, pluginManager);
    const MOCK__applicationStore = new ApplicationStore(TEST__getGenericApplicationConfig(), pluginManager);
    const queryBuilderState = new INTERNAL__BasicQueryBuilderState(MOCK__applicationStore, graphManagerState, QueryBuilderAdvancedWorkflowState.INSTANCE, undefined);
    const mapping = graphManagerState.graph.getMapping(mappingPath);
    queryBuilderState.executionContextState.setMapping(mapping);
    queryBuilderState.executionContextState.setRuntimeValue(new RuntimePointer(PackageableElementExplicitReference.create(graphManagerState.graph.getRuntime(runtimePath))));
    if (rawMappingModelCoverageAnalysisResult) {
        createSpy(graphManagerState.graphManager, 'analyzeMappingModelCoverage').mockResolvedValue(graphManagerState.graphManager.buildMappingModelCoverageAnalysisResult(rawMappingModelCoverageAnalysisResult, mapping));
    }
    const renderResult = render(_jsx(ApplicationStoreProvider, { store: MOCK__applicationStore, children: _jsx(TEST__BrowserEnvironmentProvider, { initialEntries: ['/'], children: _jsx(ApplicationFrameworkProvider, { children: _jsx(Routes, { children: _jsx(Route, { path: "*", element: _jsx(QueryBuilder, { queryBuilderState: queryBuilderState }) }) }) }) }) }));
    await waitFor(() => renderResult.getByTestId(QUERY_BUILDER_TEST_ID.QUERY_BUILDER));
    return {
        renderResult,
        queryBuilderState,
    };
};
export const TEST__setUpAccessorQueryBuilder = async (entities) => {
    const pluginManager = TEST__LegendApplicationPluginManager.create();
    pluginManager
        .usePresets([
        new Core_GraphManagerPreset(),
        new QueryBuilder_GraphManagerPreset(),
    ])
        .install();
    const graphManagerState = new GraphManagerState(pluginManager, new LogService());
    await graphManagerState.graphManager.initialize({
        env: 'test',
        tabSize: 2,
        clientConfig: {},
    });
    await graphManagerState.initializeSystem();
    await graphManagerState.graphManager.buildGraph(graphManagerState.graph, entities, graphManagerState.graphBuildState);
    const MOCK__applicationStore = new ApplicationStore(TEST__getGenericApplicationConfig(), pluginManager);
    const queryBuilderState = new AccessorQueryBuilderState(MOCK__applicationStore, undefined, graphManagerState, QueryBuilderAdvancedWorkflowState.INSTANCE, QueryBuilderActionConfig.INSTANCE);
    const renderResult = render(_jsx(ApplicationStoreProvider, { store: MOCK__applicationStore, children: _jsx(TEST__BrowserEnvironmentProvider, { initialEntries: ['/'], children: _jsx(ApplicationFrameworkProvider, { children: _jsx(Routes, { children: _jsx(Route, { path: "*", element: _jsx(QueryBuilder, { queryBuilderState: queryBuilderState }) }) }) }) }) }));
    await waitFor(() => renderResult.getByTestId(QUERY_BUILDER_TEST_ID.QUERY_BUILDER));
    return {
        renderResult,
        queryBuilderState,
    };
};
export const TEST__setUpBasicValueSpecificationEditor = (pluginManager, props) => {
    const MOCK__applicationStore = new ApplicationStore(TEST__getGenericApplicationConfig(), pluginManager);
    render(_jsx(ApplicationStoreProvider, { store: MOCK__applicationStore, children: _jsx(TEST__BrowserEnvironmentProvider, { initialEntries: ['/'], children: _jsx(ApplicationFrameworkProvider, { children: _jsx(Routes, { children: _jsx(Route, { path: "*", element: _jsx(BasicValueSpecificationEditor, { ...props }) }) }) }) }) }));
};
export const TEST__setUpV1BasicValueSpecificationEditor = (pluginManager, props) => {
    const MOCK__applicationStore = new ApplicationStore(TEST__getGenericApplicationConfig(), pluginManager);
    render(_jsx(ApplicationStoreProvider, { store: MOCK__applicationStore, children: _jsx(TEST__BrowserEnvironmentProvider, { initialEntries: ['/'], children: _jsx(ApplicationFrameworkProvider, { children: _jsx(Routes, { children: _jsx(Route, { path: "*", element: _jsx(V1_BasicValueSpecificationEditor, { ...props }) }) }) }) }) }));
};
//# sourceMappingURL=QueryBuilderComponentTestUtils.js.map