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 { forwardRef, useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import { clsx, Dialog, MenuContent, MenuContentItem, PanelLoadingIndicator, TreeView, ContextMenu, ChevronDownIcon, ChevronRightIcon, RefreshIcon, CircleNotchIcon, QuestionCircleIcon, TimesCircleIcon, CheckCircleIcon, PauseCircleIcon, BanIcon, PanelContent, ModalBody, ModalFooter, ModalHeader, ModalHeaderActions, ModalTitle, Modal, ModalFooterButton, } from '@finos/legend-art';
import { LEGEND_STUDIO_TEST_ID } from '../../../__lib__/LegendStudioTesting.js';
import { flowResult } from 'mobx';
import { WorkflowJobStatus, WorkflowStatus } from '@finos/legend-server-sdlc';
import { useApplicationStore } from '@finos/legend-application';
import { WorkflowJobTreeNodeData, WorkflowTreeNodeData, } from '../../../stores/editor/sidebar-state/WorkflowManagerState.js';
import { formatDistanceToNow, guaranteeNonNullable, guaranteeType, isNonNullable, } from '@finos/legend-shared';
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
import { CodeEditor } from '@finos/legend-lego/code-editor';
const getWorkflowStatusIcon = (workflowStatus) => {
    switch (workflowStatus) {
        case WorkflowStatus.PENDING:
            return (_jsx("div", { title: "Pipeline is suspended", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--suspended", children: _jsx(PauseCircleIcon, {}) }));
        case WorkflowStatus.IN_PROGRESS:
            return (_jsx("div", { title: "Pipeline is running", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--in-progress", children: _jsx(CircleNotchIcon, {}) }));
        case WorkflowStatus.SUCCEEDED:
            return (_jsx("div", { title: "Pipeline succeeded", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--succeeded", children: _jsx(CheckCircleIcon, {}) }));
        case WorkflowStatus.FAILED:
            return (_jsx("div", { title: "Pipeline failed", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--failed", children: _jsx(TimesCircleIcon, {}) }));
        case WorkflowStatus.CANCELED:
            return (_jsx("div", { title: "Pipeline is canceled", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--canceled", children: _jsx(BanIcon, {}) }));
        case WorkflowStatus.UNKNOWN:
        default:
            return (_jsx("div", { title: "Pipeline status is unknown", className: "workflow-manager__item__link__content__status__indicator workflow-manager__item__link__content__status__indicator--unknown", children: _jsx(QuestionCircleIcon, {}) }));
    }
};
const getWorkflowJobStatusIcon = (workflowStatus) => {
    switch (workflowStatus) {
        case WorkflowJobStatus.WAITING:
        case WorkflowJobStatus.WAITING_MANUAL:
            return (_jsx("div", { title: "Pipeline is suspended", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--suspended", children: _jsx(PauseCircleIcon, {}) }));
        case WorkflowJobStatus.IN_PROGRESS:
            return (_jsx("div", { title: "Pipeline is running", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--in-progress", children: _jsx(CircleNotchIcon, {}) }));
        case WorkflowJobStatus.SUCCEEDED:
            return (_jsx("div", { title: "Pipeline succeeded", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--succeeded", children: _jsx(CheckCircleIcon, {}) }));
        case WorkflowJobStatus.FAILED:
            return (_jsx("div", { title: "Pipeline failed", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--failed", children: _jsx(TimesCircleIcon, {}) }));
        case WorkflowJobStatus.CANCELED:
            return (_jsx("div", { title: "Pipeline is canceled", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--canceled", children: _jsx(BanIcon, {}) }));
        case WorkflowJobStatus.UNKNOWN:
        default:
            return (_jsx("div", { title: "Pipeline status is unknown", className: "workspace-workflow-jobs__item__link__content__status__indicator workspace-workflow-jobs__item__link__content__status__indicator--unknown", children: _jsx(QuestionCircleIcon, {}) }));
    }
};
const WorkflowJobLogsViewer = observer((props) => {
    const { workflowState, logState } = props;
    const applicationStore = workflowState.editorStore.applicationStore;
    const job = guaranteeNonNullable(logState.job);
    const jobIsInProgress = job.status === WorkflowJobStatus.IN_PROGRESS;
    const closeLogViewer = () => {
        logState.closeModal();
        flowResult(workflowState.fetchAllWorkflows()).catch(workflowState.editorStore.applicationStore.alertUnhandledError);
    };
    const refreshLogs = () => {
        logState.refreshJobLogs(job);
    };
    const logs = logState.logs;
    return (_jsx(Dialog, { open: Boolean(logState.job), onClose: closeLogViewer, classes: {
            root: 'editor-modal__root-container',
            container: 'editor-modal__container',
            paper: 'editor-modal__content',
        }, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "editor-modal", children: [_jsx(PanelLoadingIndicator, { isLoading: logState.fetchJobLogState.isInProgress }), _jsxs(ModalHeader, { children: [_jsx(ModalTitle, { title: `Logs for ${job.name} #${job.id}` }), _jsx(ModalHeaderActions, { children: _jsx("button", { className: "modal__header__action", disabled: !jobIsInProgress, title: "Refresh", onClick: refreshLogs, children: _jsx(RefreshIcon, {}) }) })] }), _jsx(ModalBody, { children: _jsx(CodeEditor, { inputValue: logs, isReadOnly: true, language: CODE_EDITOR_LANGUAGE.TEXT }) }), _jsx(ModalFooter, { children: _jsx(ModalFooterButton, { text: "Close", onClick: closeLogViewer, type: "secondary" }) })] }) }));
});
const WorkflowExplorerContextMenu = observer(forwardRef(function WorkflowExplorerContextMenu(props, ref) {
    const { node, workflowManagerState, workflowState, treeData } = props;
    const applicationStore = useApplicationStore();
    const retryJob = () => {
        if (node instanceof WorkflowJobTreeNodeData) {
            workflowState.retryJob(node.workflowJob, treeData);
        }
    };
    const cancelJob = () => {
        if (node instanceof WorkflowJobTreeNodeData) {
            workflowState.cancelJob(node.workflowJob, treeData);
        }
    };
    const runManualJob = () => {
        if (node instanceof WorkflowJobTreeNodeData) {
            workflowState.runManualJob(node.workflowJob, treeData);
        }
    };
    const viewLogs = () => {
        if (node instanceof WorkflowJobTreeNodeData) {
            workflowManagerState.logState.viewJobLogs(node.workflowJob);
        }
    };
    const visitWeburl = () => {
        if (node instanceof WorkflowJobTreeNodeData) {
            applicationStore.navigationService.navigator.visitAddress(node.workflowJob.webURL);
        }
        else if (node instanceof WorkflowTreeNodeData) {
            applicationStore.navigationService.navigator.visitAddress(node.workflow.webURL);
        }
    };
    return (_jsxs(MenuContent, { "data-testid": LEGEND_STUDIO_TEST_ID.EXPLORER_CONTEXT_MENU, children: [node instanceof WorkflowJobTreeNodeData && (_jsxs(_Fragment, { children: [_jsx(MenuContentItem, { onClick: viewLogs, children: "View Logs" }), _jsx(MenuContentItem, { onClick: visitWeburl, children: "Visit Job" }), node.workflowJob.status !== WorkflowJobStatus.IN_PROGRESS && (_jsx(MenuContentItem, { onClick: retryJob, children: "Retry Job" })), node.workflowJob.status === WorkflowJobStatus.IN_PROGRESS && (_jsx(MenuContentItem, { onClick: cancelJob, children: "Cancel Job" })), node.workflowJob.status === WorkflowJobStatus.WAITING_MANUAL && (_jsx(MenuContentItem, { onClick: runManualJob, children: "Run Manual Job" }))] })), node instanceof WorkflowTreeNodeData && (_jsx(MenuContentItem, { onClick: visitWeburl, children: "Visit Workflow" }))] }));
}));
const WorkflowTreeNodeContainer = (props) => {
    const { node, level, stepPaddingInRem, onNodeSelect } = props;
    const { workflowManagerState, treeData, workflowState } = props.innerProps;
    const expandIcon = !(node instanceof WorkflowTreeNodeData) ? (_jsx("div", {})) : node.isOpen ? (_jsx(ChevronDownIcon, {})) : (_jsx(ChevronRightIcon, {}));
    const nodeIcon = node instanceof WorkflowTreeNodeData
        ? getWorkflowStatusIcon(node.workflow.status)
        : getWorkflowJobStatusIcon(guaranteeType(node, WorkflowJobTreeNodeData).workflowJob.status);
    const selectNode = (event) => onNodeSelect?.(node);
    return (_jsx(ContextMenu, { content: _jsx(WorkflowExplorerContextMenu, { workflowManagerState: workflowManagerState, workflowState: workflowState, treeData: treeData, node: node }), menuProps: { elevation: 7 }, children: _jsxs("div", { className: clsx('tree-view__node__container workflow-manager__explorer__workflow-tree__node__container'), onClick: selectNode, style: {
                paddingLeft: `${level * (stepPaddingInRem ?? 1)}rem`,
                display: 'flex',
            }, children: [_jsxs("div", { className: "tree-view__node__icon workflow-manager__explorer__workflow-tree__node__icon", children: [_jsx("div", { className: "workflow-manager__explorer__workflow-tree__node__icon__expand", children: expandIcon }), _jsx("div", { className: "workflow-manager__explorer__workflow-tree__node__icon__type", children: nodeIcon })] }), node instanceof WorkflowTreeNodeData && (_jsx("a", { className: "workflow-manager__item__link", rel: "noopener noreferrer", target: "_blank", href: node.workflow.webURL, title: "See workflow detail", children: _jsxs("div", { className: "workflow-manager__item__link__content", children: [_jsxs("span", { className: "workflow-manager__item__link__content__id", children: ["#", node.label] }), _jsx("span", { className: "workflow-manager__item__link__content__created-at", children: `created ${formatDistanceToNow(node.workflow.createdAt, {
                                    includeSeconds: true,
                                    addSuffix: true,
                                })}` })] }) })), node instanceof WorkflowJobTreeNodeData && (_jsx("a", { className: "workflow-manager__item__link", rel: "noopener noreferrer", target: "_blank", href: node.workflowJob.webURL, title: "See job detail", children: _jsxs("div", { className: "workflow-manager__item__link__content", children: [_jsx("span", { className: "workflow-manager__item__link__content__id", children: node.workflowJob.name }), _jsx("span", { className: "workflow-manager__item__link__content__created-at", children: `created ${formatDistanceToNow(node.workflowJob.createdAt, {
                                    includeSeconds: true,
                                    addSuffix: true,
                                })}` })] }) }))] }) }));
};
export const WorkflowManager = observer((props) => {
    const applicationStore = useApplicationStore();
    const workflowManagerState = props.workflowManagerState;
    const isDispatchingAction = workflowManagerState.fetchWorkflowsState.isInProgress ||
        Boolean(workflowManagerState.workflowStates.find((e) => e.isExecutingWorkflowRequest));
    const renderWorkflowContent = () => (_jsxs(_Fragment, { children: [workflowManagerState.workflowStates.map((workflowState) => {
                const onNodeSelect = (node) => {
                    workflowState.onTreeNodeSelect(node, workflowState.treeData);
                };
                const getChildNodes = (node) => {
                    if (node.childrenIds && node instanceof WorkflowTreeNodeData) {
                        return node.childrenIds
                            .map((id) => workflowState.treeData.nodes.get(id))
                            .filter(isNonNullable);
                    }
                    return [];
                };
                return (_jsx(TreeView, { components: {
                        TreeNodeContainer: WorkflowTreeNodeContainer,
                    }, treeData: workflowState.treeData, onNodeSelect: onNodeSelect, getChildNodes: getChildNodes, innerProps: {
                        workflowManagerState,
                        workflowState: workflowState,
                        treeData: workflowState.treeData,
                    } }, workflowState.uuid));
            }), workflowManagerState.logState.job && (_jsx(WorkflowJobLogsViewer, { logState: workflowManagerState.logState, workflowState: workflowManagerState }))] }));
    const refresh = applicationStore.guardUnhandledError(() => flowResult(workflowManagerState.fetchAllWorkflows()));
    useEffect(() => {
        flowResult(workflowManagerState.fetchAllWorkflows()).catch(applicationStore.alertUnhandledError);
    }, [applicationStore, workflowManagerState]);
    return (_jsxs("div", { className: "panel workflow-manager", children: [_jsxs("div", { className: "panel__header side-bar__header", children: [_jsx("div", { className: "panel__header__title workflow-manager__header__title", children: _jsx("div", { className: "panel__header__title__content side-bar__header__title__content", children: "WORKFLOW MANAGER" }) }), _jsx("div", { className: "panel__header__actions side-bar__header__actions", children: _jsx("button", { className: clsx('panel__header__action side-bar__header__action workflow-manager__refresh-btn', {
                                'workflow-manager__refresh-btn--loading': isDispatchingAction,
                            }), disabled: isDispatchingAction, onClick: refresh, tabIndex: -1, title: "Refresh", children: _jsx(RefreshIcon, {}) }) })] }), _jsxs("div", { className: "panel__content side-bar__content", children: [_jsx(PanelLoadingIndicator, { isLoading: isDispatchingAction }), _jsxs("div", { className: "panel side-bar__panel", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__content", children: "WORKFLOWS" }) }), _jsx("div", { className: "side-bar__panel__header__changes-count", "data-testid": LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT, children: workflowManagerState.workflowStates.length })] }), _jsx(PanelContent, { children: renderWorkflowContent() })] })] })] }));
});
//# sourceMappingURL=WorkflowManager.js.map