import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { useState, useCallback, forwardRef } from 'react';
import { observer } from 'mobx-react-lite';
import { useDrop } from 'react-dnd';
import { MAPPING_TEST_EDITOR_TAB_TYPE, TEST_RESULT, } from '../../../../stores/editor/editor-state/element-editor-state/mapping/legacy/DEPRECATED__MappingTestState.js';
import { clsx, ContextMenu, ProgressBar, PlayIcon, EmptyCircleIcon, TimesCircleIcon, CheckCircleIcon, CircleNotchIcon, PlusIcon, EmptyStopCircleIcon, ExclamationCircleIcon, PauseCircleIcon, PanelDropZone, MenuContent, MenuContentItem, Panel, WarningIcon, } from '@finos/legend-art';
import { CORE_DND_TYPE, } from '../../../../stores/editor/utils/DnDUtils.js';
import { ClassMappingSelectorModal } from './MappingExecutionBuilder.js';
import { flowResult } from 'mobx';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { useApplicationStore } from '@finos/legend-application';
import { SetImplementation } from '@finos/legend-graph';
import { MappingEditorState } from '../../../../stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js';
export const MappingTestExplorerContextMenu = observer(forwardRef(function MappingTestExplorerContextMenu(props, ref) {
    const { mappingTestState, isReadOnly, showCreateNewTestModal } = props;
    const applicationStore = useApplicationStore();
    const runMappingTest = () => {
        if (mappingTestState) {
            flowResult(mappingTestState.runTest()).catch(applicationStore.alertUnhandledError);
        }
    };
    const removeMappingTest = () => {
        if (mappingTestState) {
            flowResult(mappingTestState.mappingEditorState.deleteTest(mappingTestState.test)).catch(applicationStore.alertUnhandledError);
        }
    };
    const toggleSkipTest = () => mappingTestState?.toggleSkipTest();
    const viewTestResult = () => {
        if (mappingTestState) {
            mappingTestState.mappingEditorState.openTest(mappingTestState.test, MAPPING_TEST_EDITOR_TAB_TYPE.RESULT);
        }
    };
    const editTest = () => {
        if (mappingTestState) {
            mappingTestState.mappingEditorState.openTest(mappingTestState.test, MAPPING_TEST_EDITOR_TAB_TYPE.SETUP);
        }
    };
    return (_jsxs(MenuContent, { ref: ref, children: [mappingTestState && (_jsx(MenuContentItem, { onClick: runMappingTest, children: "Run" })), mappingTestState && mappingTestState.result !== TEST_RESULT.NONE && (_jsx(MenuContentItem, { onClick: viewTestResult, children: "View Result" })), mappingTestState && (_jsx(MenuContentItem, { onClick: editTest, children: "Edit" })), mappingTestState && (_jsx(MenuContentItem, { onClick: toggleSkipTest, children: mappingTestState.isSkipped ? 'Unskip' : 'Skip' })), !isReadOnly && mappingTestState && (_jsx(MenuContentItem, { onClick: removeMappingTest, children: "Delete" })), !isReadOnly && !mappingTestState && showCreateNewTestModal && (_jsx(MenuContentItem, { onClick: showCreateNewTestModal, children: "Create new test" }))] }));
}));
export const MappingTestStatusIndicator = (props) => {
    const { testState } = props;
    if (testState.isSkipped) {
        return (_jsx("div", { title: "Test is skipped", className: "mapping-test-status-indicator mapping-test-status-indicator--skipped", children: _jsx(EmptyStopCircleIcon, {}) }));
    }
    if (testState.isRunningTest) {
        return (_jsx("div", { title: "Test is running", className: "mapping-test-status-indicator mapping-test-status-indicator--in-progress", children: _jsx(CircleNotchIcon, {}) }));
    }
    return (_jsxs(_Fragment, { children: [testState.result === TEST_RESULT.NONE && (_jsx("div", { title: "Test did not run", className: "mapping-test-status-indicator mapping-test-status-indicator--none", children: _jsx(EmptyCircleIcon, {}) })), testState.result === TEST_RESULT.ERROR && (_jsx("div", { title: "Test failed due to error", className: "mapping-test-status-indicator mapping-test-status-indicator--error", children: _jsx(TimesCircleIcon, {}) })), testState.result === TEST_RESULT.FAILED && (_jsx("div", { title: "Test failed assertion", className: "mapping-test-status-indicator mapping-test-status-indicator--failed", children: _jsx(ExclamationCircleIcon, {}) })), testState.result === TEST_RESULT.PASSED && (_jsx("div", { title: "Test passed", className: "mapping-test-status-indicator mapping-test-status-indicator--passed", children: _jsx(CheckCircleIcon, {}) }))] }));
};
export const MappingTestExplorer = observer((props) => {
    const { isReadOnly, testState } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState);
    const openTest = applicationStore.guardUnhandledError(() => flowResult(mappingEditorState.openTest(testState.test)));
    const runTest = applicationStore.guardUnhandledError(() => flowResult(testState.runTest()));
    const cancelTest = () => {
        testState.setIsRunningTest(false);
        testState.setTestRunPromise(undefined);
    };
    const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] = useState(false);
    const onContextMenuOpen = () => setIsSelectedFromContextMenu(true);
    const onContextMenuClose = () => setIsSelectedFromContextMenu(false);
    const isActive = mappingEditorState.currentTabState === testState;
    return (_jsx(ContextMenu, { content: _jsx(MappingTestExplorerContextMenu, { mappingTestState: testState, isReadOnly: isReadOnly }), menuProps: { elevation: 7 }, onOpen: onContextMenuOpen, onClose: onContextMenuClose, children: _jsxs("div", { className: clsx('mapping-test-explorer__item', {
                'mapping-explorer__item--selected-from-context-menu': !isActive && isSelectedFromContextMenu,
            }, { 'mapping-test-explorer__item--active': isActive }), children: [_jsxs("button", { className: "mapping-test-explorer__item__label", onClick: openTest, tabIndex: -1, children: [_jsx("div", { className: "mapping-test-explorer__item__label__icon mapping-test-explorer__test-result-indicator__container", children: _jsx(MappingTestStatusIndicator, { testState: testState }) }), _jsx("div", { className: "mapping-test-explorer__item__label__text", children: testState.test.name }), testState.result !== TEST_RESULT.NONE && (_jsxs("div", { className: "mapping-test-explorer__item__run-time", children: [testState.runTime, "ms"] }))] }), _jsx("div", { className: "mapping-test-explorer__item__actions", children: testState.isRunningTest ? (_jsx("button", { className: "mapping-test-explorer__item__action mapping-test-explorer__stop-test-btn", onClick: cancelTest, disabled: testState.mappingEditorState.isRunningAllTests, tabIndex: -1, title: `Stop ${testState.test.name}`, children: _jsx(PauseCircleIcon, {}) })) : (_jsx("button", { className: "mapping-test-explorer__item__action mapping-test-explorer__run-test-btn", onClick: runTest, disabled: testState.mappingEditorState.isRunningAllTests, tabIndex: -1, title: `Run ${testState.test.name}`, children: _jsx(PlayIcon, {}) })) })] }) }));
});
export const MappingTestsExplorer = observer((props) => {
    const { isReadOnly } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState);
    const runAllTests = applicationStore.guardUnhandledError(() => flowResult(mappingEditorState.runTests()));
    // all test run report summary
    const numberOfTests = mappingEditorState.DEPRECATED_mappingTestStates.length;
    const numberOfTestsPassed = mappingEditorState.DEPRECATED_mappingTestStates.filter((testState) => testState.result === TEST_RESULT.PASSED).length;
    const numberOfTestsFailed = mappingEditorState.DEPRECATED_mappingTestStates.filter((testState) => testState.result === TEST_RESULT.FAILED ||
        testState.result === TEST_RESULT.ERROR).length;
    const numberOfTestSkipped = mappingEditorState.DEPRECATED_mappingTestStates.filter((testState) => testState.isSkipped).length;
    const percentageTestRun = Math.floor((mappingEditorState.DEPRECATED_mappingTestStates.filter((testState) => testState.result !== TEST_RESULT.NONE).length /
        numberOfTests) *
        100);
    let testReportSummary = '';
    switch (mappingEditorState.testSuiteResult) {
        case TEST_RESULT.NONE:
            testReportSummary = mappingEditorState.isRunningAllTests
                ? `Running ${numberOfTests} tests...`
                : 'No tests run!';
            break;
        case TEST_RESULT.FAILED:
            testReportSummary = `${numberOfTestsFailed} of ${numberOfTests} failed`;
            break;
        case TEST_RESULT.PASSED:
            testReportSummary =
                numberOfTestsPassed === numberOfTests
                    ? `All ${numberOfTests} passed`
                    : `${numberOfTestsPassed} of ${numberOfTests} passed`;
            break;
        default:
            break;
    }
    // Drag and Drop
    const handleDrop = useCallback((item) => {
        if (isReadOnly) {
            return;
        }
        if (item.data instanceof SetImplementation) {
            flowResult(mappingEditorState.createNewTest(item.data)).catch(applicationStore.alertUnhandledError);
        }
    }, [applicationStore.alertUnhandledError, isReadOnly, mappingEditorState]);
    const [{ isDragOver }, dropConnector] = useDrop(() => ({
        accept: CORE_DND_TYPE.MAPPING_EXPLORER_CLASS_MAPPING,
        drop: (item) => handleDrop(item),
        collect: (monitor) => ({
            isDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDrop]);
    // Class mapping selector
    const [openClassMappingSelectorModal, setOpenClassMappingSelectorModal] = useState(false);
    const openMigrationtool = () => mappingEditorState.openMigrationTool();
    const showClassMappingSelectorModal = () => setOpenClassMappingSelectorModal(true);
    const hideClassMappingSelectorModal = () => setOpenClassMappingSelectorModal(false);
    const changeClassMapping = useCallback((setImplementation) => {
        if (setImplementation) {
            flowResult(mappingEditorState.createNewTest(setImplementation)).catch(applicationStore.alertUnhandledError);
            hideClassMappingSelectorModal();
        }
    }, [applicationStore, mappingEditorState]);
    return (_jsxs(Panel, { className: "mapping-test-explorer", children: [_jsxs("div", { className: "panel__header", title: testReportSummary, children: [_jsxs("div", { className: "mapping-test-explorer__header__info", children: [_jsx("div", { className: "panel__header__title", children: _jsxs("div", { className: "panel__header__title__content mapping-test-explorer__header__report", children: [_jsxs("div", { className: "mapping-test-explorer__header__report__overview", children: [_jsxs("div", { className: "mapping-test-explorer__header__report__overview__stat mapping-test-explorer__header__report__overview__stat--total", children: [numberOfTests, " total"] }), _jsxs("div", { className: "mapping-test-explorer__header__report__overview__stat mapping-test-explorer__header__report__overview__stat--passed", children: [numberOfTestsPassed, " passed"] }), _jsxs("div", { className: "mapping-test-explorer__header__report__overview__stat mapping-test-explorer__header__report__overview__stat--failed", children: [numberOfTestsFailed, " failed"] }), Boolean(numberOfTestSkipped) && (_jsxs("div", { className: "mapping-test-explorer__header__report__overview__stat mapping-test-explorer__header__report__overview__stat--skipped", children: [numberOfTestSkipped, " skipped"] }))] }), mappingEditorState.testSuiteResult !== TEST_RESULT.NONE && (_jsxs("div", { className: "mapping-test-explorer__header__report__time", children: [mappingEditorState.allTestRunTime, "ms"] }))] }) }), _jsxs("div", { className: "panel__header__actions", children: [Boolean(mappingEditorState.mapping.test.length) && (_jsx("button", { className: "panel__header__action", onClick: openMigrationtool, disabled: isReadOnly, tabIndex: -1, title: "Please migrate to new mapping test framework", children: _jsx(WarningIcon, {}) })), _jsx("button", { className: "panel__header__action", onClick: showClassMappingSelectorModal, disabled: isReadOnly, tabIndex: -1, title: "Add Test", children: _jsx(PlusIcon, {}) }), _jsx("button", { className: "panel__header__action", onClick: runAllTests, disabled: !mappingEditorState.DEPRECATED_mappingTestStates.length ||
                                            mappingEditorState.isRunningAllTests, tabIndex: -1, title: "Run All Tests", children: _jsx(PlayIcon, {}) })] })] }), _jsx("div", { className: "mapping-test-explorer__header__status", children: _jsx(ProgressBar, { className: `mapping-test-explorer__header__progress-bar mapping-test-explorer__header__progress-bar--${mappingEditorState.testSuiteResult.toLowerCase()}`, classes: {
                                bar: `mapping-test-explorer__header__progress-bar__bar mapping-test-explorer__header__progress-bar__bar--${mappingEditorState.testSuiteResult.toLowerCase()}`,
                            }, variant: "determinate", value: percentageTestRun }) })] }), _jsx(ContextMenu, { className: "panel__content", disabled: isReadOnly, content: _jsx(MappingTestExplorerContextMenu, { isReadOnly: isReadOnly, showCreateNewTestModal: showClassMappingSelectorModal }), menuProps: { elevation: 7 }, children: _jsx(PanelDropZone, { isDragOver: isDragOver && !isReadOnly, dropTargetConnector: dropConnector, children: _jsx("div", { className: "mapping-test-explorer__content", children: Boolean(mappingEditorState.DEPRECATED_mappingTestStates.length) &&
                            mappingEditorState.DEPRECATED_mappingTestStates.slice().map((testState) => (_jsx(MappingTestExplorer, { testState: testState, isReadOnly: isReadOnly }, testState.test._UUID))) }) }) }), openClassMappingSelectorModal && (_jsx(ClassMappingSelectorModal, { mappingEditorState: mappingEditorState, hideClassMappingSelectorModal: hideClassMappingSelectorModal, changeClassMapping: changeClassMapping }))] }));
});
//# sourceMappingURL=MappingTestsExplorer.js.map