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 { ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, PlusIcon, ContextMenu, MenuContent, MenuContentItem, PanelListSelectorItem, ControlledDropdownMenu, ResizablePanelSplitterLine, PanelContent, Panel, Badge, PanelListSelectorItemLabel, PanelFormBooleanField, PanelHeaderActions, PanelForm, PURE_FunctionIcon, LongArrowRightIcon, PanelLoadingIndicator, PanelFormValidatedTextField, TimesIcon, clsx, PanelHeader, CaretDownIcon, } from '@finos/legend-art';
import { Profile, StereotypeExplicitReference, generateFunctionPrettyName, stub_Profile, stub_Stereotype, stub_Tag, stub_TaggedValue, validate_ServicePattern, } from '@finos/legend-graph';
import { observer } from 'mobx-react-lite';
import { useApplicationStore } from '@finos/legend-application';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { HostedServiceFunctionActivatorEditorState, ACTIVATOR_EDITOR_TAB, } from '../../../../stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js';
import { hostedService_setAutoActivateUpdates, hostedService_setDocumentation, hostedService_setPattern, hostedService_removePatternParameter, hostedService_setStoreModel, hostedServices_deleteAction, } from '../../../../stores/graph-modifier/DSL_FunctionActivator_GraphModifierHelper.js';
import { useCallback, useEffect, useRef, useState } from 'react';
import { prettyCONSTName } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { ActivatorOwnershipForm } from './ActivatorFormComponents.js';
import { annotatedElement_addStereotype, annotatedElement_addTaggedValue, annotatedElement_deleteStereotype, annotatedElement_deleteTaggedValue, } from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
import { CORE_DND_TYPE, } from '../../../../stores/editor/utils/DnDUtils.js';
import { useDrop } from 'react-dnd';
import { TaggedValueDragPreviewLayer, TaggedValueEditor, } from '../uml-editor/TaggedValueEditor.js';
import { StereotypeDragPreviewLayer, StereotypeSelector, } from '../uml-editor/StereotypeSelector.js';
import { UnsupportedEditorPanel } from '../UnsupportedElementEditor.js';
import { ActivatorArtifactViewer } from './ActivatorArtifactViewer.js';
const renderEditorPostAction = (postDeploymentAction, isReadOnly, plugins, activatorState) => {
    const extraPostDeploymentActionEditorRenderers = plugins.flatMap((plugin) => plugin.getExtraActionEditorRenderers?.() ?? []);
    for (const editorRenderer of extraPostDeploymentActionEditorRenderers) {
        if (postDeploymentAction.properties) {
            const editor = editorRenderer(postDeploymentAction.properties, activatorState, isReadOnly, postDeploymentAction);
            if (editor) {
                return editor;
            }
        }
    }
    return (_jsx(UnsupportedEditorPanel, { isReadOnly: true, text: "Can't display action in form mode" }));
};
const HostedServicesActionEditor = observer((props) => {
    const { activatorState, isReadOnly } = props;
    const editorStore = useEditorStore();
    const plugins = editorStore.pluginManager.getApplicationPlugins();
    const editorState = editorStore.tabManagerState.getCurrentEditorState(HostedServiceFunctionActivatorEditorState);
    const deleteAction = (action, index) => () => {
        hostedServices_deleteAction(editorState.activator, index);
    };
    const postDeploymentActionOptions = plugins
        .flatMap((plugin) => plugin.getExtraPostDeploymentTypes?.() ?? [])
        .map((type) => ({
        value: type,
        label: type,
    }));
    const addAction = (actionType) => () => {
        const extraActions = plugins.flatMap((plugin) => plugin.getExtraActionCreators?.() ?? []);
        for (const creator of extraActions) {
            creator(actionType, activatorState.activator, editorStore.changeDetectionState.observerContext);
        }
    };
    const selectAction = (postDeploymentAction) => {
        editorState.setSelectedAction(postDeploymentAction);
    };
    const getPostDeploymentActionLabel = (postDeploymentAction) => {
        const extraPostDeploymentActionClassifier = plugins.flatMap((plugin) => plugin.getExtraPostDeploymentActionClassifierGetters?.() ?? []);
        for (const classify of extraPostDeploymentActionClassifier) {
            if (postDeploymentAction.properties) {
                const label = classify(postDeploymentAction.properties);
                if (label) {
                    return label;
                }
            }
        }
        return 'unknown type';
    };
    return (_jsx("div", { className: "action-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx("div", { className: "action-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 200, minSize: 100, children: _jsxs(Panel, { children: [_jsx(PanelHeader, { title: "actions", children: _jsx(PanelHeaderActions, { children: _jsx(ControlledDropdownMenu, { title: "Create action", className: "panel__header__action", disabled: isReadOnly, content: postDeploymentActionOptions.map((postDeploymentActionType) => (_jsxs(MenuContentItem, { onClick: addAction(postDeploymentActionType.value), children: ["New ", postDeploymentActionType.label, " Action"] }, postDeploymentActionType.value))), menuProps: {
                                                            anchorOrigin: {
                                                                vertical: 'bottom',
                                                                horizontal: 'right',
                                                            },
                                                            transformOrigin: {
                                                                vertical: 'top',
                                                                horizontal: 'right',
                                                            },
                                                            elevation: 7,
                                                        }, children: _jsx(PlusIcon, {}) }) }) }), _jsx(PanelContent, { children: editorState.activator.actions.map((actionItem, idx) => (_jsx(ContextMenu, { disabled: isReadOnly, content: _jsx(MenuContent, { children: _jsx(MenuContentItem, { onClick: deleteAction(actionItem, idx), children: "Delete" }) }), menuProps: { elevation: 7 }, children: _jsxs(PanelListSelectorItem, { onSelect: () => selectAction(actionItem), isSelected: actionItem === editorState.selectedAction, children: [_jsx(PanelListSelectorItemLabel, { title: `Action ${idx + 1}` }), _jsx(Badge, { className: "badge--right", title: getPostDeploymentActionLabel(actionItem) })] }) }, actionItem.hashCode))) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: editorState.selectedAction &&
                                        renderEditorPostAction(editorState.selectedAction, isReadOnly, plugins, editorState) })] }) }) })] }) }));
});
export const HostedServiceFunctionActivatorEditor = observer(() => {
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const editorState = editorStore.tabManagerState.getCurrentEditorState(HostedServiceFunctionActivatorEditorState);
    const activatorElement = editorState.element;
    const isReadOnly = editorState.isReadOnly;
    const selectedTab = editorState.selectedTab;
    const activator = editorState.activator;
    let addButtonTitle = '';
    switch (selectedTab) {
        case ACTIVATOR_EDITOR_TAB.TAGGED_VALUES:
            addButtonTitle = 'Add tagged value';
            break;
        case ACTIVATOR_EDITOR_TAB.STEREOTYPES:
            addButtonTitle = 'Add stereotype';
            break;
        default:
            break;
    }
    // Tagged Values
    const add = () => {
        if (!isReadOnly) {
            if (selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES) {
                annotatedElement_addTaggedValue(activatorElement, stub_TaggedValue(stub_Tag(stub_Profile())));
            }
            else if (selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES) {
                annotatedElement_addStereotype(activatorElement, StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())));
            }
        }
    };
    const handleDropTaggedValue = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Profile) {
            annotatedElement_addTaggedValue(activatorElement, stub_TaggedValue(stub_Tag(item.data.packageableElement)));
        }
    }, [activatorElement, isReadOnly]);
    const [{ isTaggedValueDragOver }, taggedValueDropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
        drop: (item) => handleDropTaggedValue(item),
        collect: (monitor) => ({
            isTaggedValueDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropTaggedValue]);
    const taggedValueRef = useRef(null);
    taggedValueDropConnector(taggedValueRef);
    // Stereotype
    const handleDropStereotype = useCallback((item) => {
        if (!isReadOnly && item.data.packageableElement instanceof Profile) {
            annotatedElement_addStereotype(activatorElement, StereotypeExplicitReference.create(stub_Stereotype(item.data.packageableElement)));
        }
    }, [activatorElement, isReadOnly]);
    const [{ isStereotypeDragOver }, stereotypeDropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
        drop: (item) => handleDropStereotype(item),
        collect: (monitor) => ({
            isStereotypeDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropStereotype]);
    const stereotypeRef = useRef(null);
    stereotypeDropConnector(stereotypeRef);
    const _deleteStereotype = (val) => () => annotatedElement_deleteStereotype(activatorElement, val);
    const _deleteTaggedValue = (val) => () => annotatedElement_deleteTaggedValue(activatorElement, val);
    const changeTab = (tab) => () => editorState.setSelectedTab(tab);
    const visitFunction = () => editorState.editorStore.graphEditorMode.openElement(activator.function.value);
    const validate = () => {
        flowResult(editorState.validate()).catch(applicationStore.alertUnhandledError);
    };
    const renderArtifact = () => {
        flowResult(editorState.renderArtifact()).catch(applicationStore.alertUnhandledError);
    };
    const deploy = () => {
        flowResult(editorState.deployToSandbox()).catch(applicationStore.alertUnhandledError);
    };
    const changeDocumentation = (event) => {
        if (!isReadOnly) {
            hostedService_setDocumentation(activator, event.target.value);
        }
    };
    const toggleUseStoreModel = () => {
        hostedService_setStoreModel(activator, !activator.storeModel);
    };
    const toggleAutoActivateUpdates = () => {
        hostedService_setAutoActivateUpdates(activator, !activator.autoActivateUpdates);
    };
    const getValidationMessage = (inputPattern) => {
        const patternValidationResult = validate_ServicePattern(inputPattern);
        return patternValidationResult
            ? patternValidationResult.messages[0]
            : undefined;
    };
    //Pattern
    const patternRef = useRef(null);
    const [pattern, setPattern] = useState(activator.pattern);
    const updatePattern = (newPattern) => {
        if (!isReadOnly) {
            hostedService_setPattern(activator, newPattern);
        }
    };
    const removePatternParameter = (val) => () => {
        hostedService_removePatternParameter(activator, val);
        setPattern(activator.pattern);
    };
    useEffect(() => {
        patternRef.current?.focus();
    }, [editorState]);
    return (_jsx("div", { className: "hosted-service-function-activator-editor", children: _jsxs(Panel, { children: [_jsx(PanelHeader, { title: "Rest Service Application" }), _jsx(PanelLoadingIndicator, { isLoading: Boolean(editorState.validateState.isInProgress ||
                        editorState.renderArtifactState.isInProgress ||
                        editorState.deployState.isInProgress) }), _jsxs("div", { className: "panel__header function-editor__tabs__header", children: [_jsx("div", { className: "function-editor__tabs", children: Object.values(ACTIVATOR_EDITOR_TAB).map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('function-editor__tab', {
                                    'function-editor__tab--active': tab === selectedTab,
                                }), children: prettyCONSTName(tab) }, tab))) }), selectedTab !== ACTIVATOR_EDITOR_TAB.DEFINITION && (_jsx("button", { className: "panel__header__action", disabled: isReadOnly, onClick: add, tabIndex: -1, title: addButtonTitle, children: _jsx(PlusIcon, {}) }))] }), _jsxs(PanelContent, { children: [selectedTab === ACTIVATOR_EDITOR_TAB.DEFINITION && (_jsxs("div", { children: [_jsxs("div", { className: "hosted-service-function-activator-editor__header", children: [_jsx("div", { className: "hosted-service-function-activator-editor__header__label", children: "Rest Service Activator" }), _jsxs("div", { className: "hosted-service-function-activator-editor__header__actions", children: [_jsxs("div", { className: "hosted-service-function-activator-editor__header__actions btn__dropdown-combo--primary", children: [_jsx("button", { className: "hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary", onClick: validate, disabled: editorState.validateState.isInProgress, tabIndex: -1, title: "Click Validate to verify your activator before deployment", children: "Validate" }), _jsx(ControlledDropdownMenu, { className: "hosted-service-function-activator-editor__header__actions btn__dropdown-combo btn__dropdown-combo__dropdown-btn", title: "activator-artifact-dropdown", content: _jsx(MenuContent, { children: _jsx(MenuContentItem, { className: "btn__dropdown-combo__option", onClick: renderArtifact, title: "Render artifact", children: "Render Artifact" }) }), menuProps: {
                                                                anchorOrigin: {
                                                                    vertical: 'bottom',
                                                                    horizontal: 'right',
                                                                },
                                                                transformOrigin: {
                                                                    vertical: 'top',
                                                                    horizontal: 'right',
                                                                },
                                                            }, children: _jsx(CaretDownIcon, {}) })] }), _jsx("div", { className: "hosted-service-function-activator-editor__header__actions btn__dropdown-combo--primary", children: _jsx("button", { className: "hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary", onClick: deploy, disabled: editorState.deployState.isInProgress, title: "Deploy to sandbox", tabIndex: -1, children: "Deploy to Sandbox" }) })] })] }), _jsx(PanelForm, { children: _jsx(PanelFormValidatedTextField, { ref: patternRef, name: "URL Pattern", isReadOnly: isReadOnly, className: "service-editor__pattern__input", errorMessageClassName: "service-editor__pattern__input", prompt: _jsxs(_Fragment, { children: ["Specifies the URL pattern of the service (e.g. /myService/", _jsx("span", { className: "service-editor__pattern__example__param", children: `{param}` }), ")"] }), update: (value) => {
                                            updatePattern(value ?? '');
                                        }, validate: getValidationMessage, value: pattern }) }), _jsx(PanelForm, { children: _jsxs("div", { className: "panel__content__form__section service-editor__parameters", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Parameters" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "URL parameters (each must be surrounded by curly braces) will be passed as arguments for the execution query. Note that if the service is configured to use multi-execution, one of the URL parameters must be chosen as the execution key." }), _jsxs("div", { className: "service-editor__parameters__list", children: [!activator.patternParameters.length && (_jsx("div", { className: "service-editor__parameters__list__empty", children: "No parameter" })), Boolean(activator.patternParameters.length) &&
                                                        activator.patternParameters.map((parameter) => (_jsxs("div", { className: "service-editor__parameter", children: [_jsx("div", { className: "service-editor__parameter__text", children: parameter }), _jsx("div", { className: "service-editor__parameter__actions", children: _jsx("button", { className: "service-editor__parameter__action", disabled: isReadOnly, onClick: removePatternParameter(parameter), title: "Remove parameter", tabIndex: -1, children: _jsx(TimesIcon, {}) }) })] }, parameter)))] })] }) }), _jsxs(PanelForm, { children: [_jsx("div", { className: "panel__content__form__section", children: _jsx("div", { className: "panel__content__form__section__header__label", children: "Function" }) }), _jsx("div", { className: "hosted-service-function-activator-editor__configuration__items", children: _jsxs("div", { className: "hosted-service-function-activator-editor__configuration__item", children: [_jsx("div", { className: "btn--sm hosted-service-function-activator-editor__configuration__item__label", children: _jsx(PURE_FunctionIcon, {}) }), _jsx("input", { className: "panel__content__form__section__input", spellCheck: false, disabled: true, value: generateFunctionPrettyName(activator.function.value, {
                                                            fullPath: true,
                                                            spacing: false,
                                                        }) }), _jsx("button", { className: "btn--dark btn--sm hosted-service-function-activator-editor__configuration__item__btn", onClick: visitFunction, tabIndex: -1, title: "See Function", children: _jsx(LongArrowRightIcon, {}) })] }) })] }), _jsx(PanelForm, { children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Documentation" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: `Provide a brief description of the service's functionalities and usage` }), _jsx("textarea", { className: "panel__content__form__section__textarea service-editor__documentation__input", spellCheck: false, disabled: isReadOnly, value: activator.documentation, onChange: changeDocumentation })] }) }), _jsx(PanelForm, { children: _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: activator.autoActivateUpdates, name: "Auto Activate Updates", prompt: "Specifies if the new generation should be automatically activated;\n          only valid when latest revision is selected upon service\n          registration", update: toggleAutoActivateUpdates }) }), _jsx(PanelForm, { children: _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: activator.storeModel, name: "Store Model", prompt: "Use Store Model (slower)", update: toggleUseStoreModel }) }), _jsx(PanelForm, { children: _jsx(ActivatorOwnershipForm, { activator: activator, isReadOnly: isReadOnly }) })] })), selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES && (_jsxs("div", { ref: taggedValueRef, className: clsx('panel__content__lists', {
                                'panel__content__lists--dnd-over': isTaggedValueDragOver && !isReadOnly,
                            }), children: [_jsx(TaggedValueDragPreviewLayer, {}), activatorElement.taggedValues.map((taggedValue) => (_jsx(TaggedValueEditor, { annotatedElement: activatorElement, taggedValue: taggedValue, deleteValue: _deleteTaggedValue(taggedValue), isReadOnly: isReadOnly, darkTheme: true }, taggedValue._UUID)))] })), selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES && (_jsxs("div", { ref: stereotypeRef, className: clsx('panel__content__lists', {
                                'panel__content__lists--dnd-over': isStereotypeDragOver && !isReadOnly,
                            }), children: [_jsx(StereotypeDragPreviewLayer, {}), activatorElement.stereotypes.map((stereotype) => (_jsx(StereotypeSelector, { annotatedElement: activatorElement, stereotype: stereotype, deleteStereotype: _deleteStereotype(stereotype), isReadOnly: isReadOnly, darkTheme: true }, stereotype.value._UUID)))] })), selectedTab === ACTIVATOR_EDITOR_TAB.ACTIONS && (_jsx("div", { className: clsx('panel__content__lists'), children: _jsx(HostedServicesActionEditor, { activatorState: editorState, isReadOnly: isReadOnly }) })), _jsx(ActivatorArtifactViewer, { artifact: editorState.artifact, setArtifact: (value) => editorState.setArtifact(value), darkMode: !applicationStore.layoutService
                                .TEMPORARY__isLightColorThemeEnabled })] })] }) }));
});
//# sourceMappingURL=HostedServiceFunctionActivatorEditor.js.map