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, useEffect, useCallback, forwardRef } from 'react';
import { observer } from 'mobx-react-lite';
import { LakehouseRuntimeEditorState, PackageableRuntimeEditorState, RuntimeEditorRuntimeTabState, IdentifiedConnectionsEditorTabState, IdentifiedConnectionsPerClassEditorTabState, IdentifiedConnectionsPerStoreEditorTabState, LakehouseRuntimeType, } from '../../../stores/editor/editor-state/element-editor-state/RuntimeEditorState.js';
import { clsx, Dialog, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, TreeView, ContextMenu, CustomSelectorInput, createFilter, BlankPanelContent, MenuContent, MenuContentItem, BlankPanelPlaceholder, PURE_RuntimeIcon, PURE_ConnectionIcon, PURE_ModelStoreIcon, PURE_ClassIcon, PURE_MappingIcon, ChevronDownIcon, ChevronRightIcon, PlusIcon, TimesIcon, LongArrowRightIcon, CogIcon, CaretRightIcon, PanelDropZone, Panel, PanelContent, PanelHeader, ModalHeader, ModalTitle, ModalHeaderActions, ModalBody, Modal, PanelHeaderActions, PanelHeaderActionItem, LockIcon, PanelFormTextField, PanelFormSection, } from '@finos/legend-art';
import { getElementIcon } from '../../ElementIconUtils.js';
import { ConnectionEditor } from './connection-editor/ConnectionEditor.js';
import { CORE_DND_TYPE, ElementDragSource, } from '../../../stores/editor/utils/DnDUtils.js';
import { useDrop } from 'react-dnd';
import { assertErrorThrown, prettyCONSTName } from '@finos/legend-shared';
import { useEditorStore } from '../EditorStoreProvider.js';
import { Connection, ConnectionPointer, Runtime, IdentifiedConnection, RuntimePointer, ModelStore, Mapping, Class, Store, PackageableConnection, JsonModelConnection, XmlModelConnection, FlatDataConnection, RelationalDatabaseConnection, PackageableElementExplicitReference, ModelChainConnection, generateIdentifiedConnectionId, } from '@finos/legend-graph';
import { useApplicationNavigationContext, useApplicationStore, } from '@finos/legend-application';
import { buildElementOption, } from '@finos/legend-lego/graph-editor';
import { runtime_addIdentifiedConnection, runtime_deleteIdentifiedConnection, } from '../../../stores/graph-modifier/DSL_Mapping_GraphModifierHelper.js';
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../__lib__/LegendStudioApplicationNavigationContext.js';
import { CUSTOM_LABEL } from '../../../stores/editor/NewElementState.js';
import { lakehouseRuntime_setWarehouse } from '../../../stores/graph-modifier/DSL_LakehouseRuntime_GraphModifierHelper.js';
import { useAuth } from 'react-oidc-context';
import { flowResult } from 'mobx';
const getConnectionTooltipText = (connection, editorStore) => {
    const connectionValue = connection instanceof ConnectionPointer
        ? connection.packageableConnection.value.connectionValue
        : connection;
    if (connectionValue instanceof JsonModelConnection) {
        return `JSON model connection \u2022 Class ${connectionValue.class.value.path}`;
    }
    else if (connectionValue instanceof XmlModelConnection) {
        return `XML model connection \u2022 Class ${connectionValue.class.value.path}`;
    }
    else if (connectionValue instanceof FlatDataConnection) {
        return `Flat-data connection \u2022 Flat-data store ${connectionValue.store.value.path}`;
    }
    else if (connectionValue instanceof RelationalDatabaseConnection) {
        return connectionValue.store
            ? `Relational database connection \u2020 database store ${connectionValue.store.value.path}`
            : `Relational database connection`;
    }
    else if (connectionValue instanceof ModelChainConnection) {
        return `Model chain connection \u2022`;
    }
    const extraConnectionToolTipTexts = editorStore.pluginManager
        .getApplicationPlugins()
        .flatMap((plugin) => plugin.getExtraRuntimeConnectionTooltipTextBuilders?.() ?? []);
    for (const builder of extraConnectionToolTipTexts) {
        const tooltipText = builder(connectionValue);
        if (tooltipText) {
            return tooltipText;
        }
    }
    return `Unknown connection`;
};
const IdentifiedConnectionsPerStoreExplorerContextMenu = observer(forwardRef(function IdentifiedConnectionsPerStoreExplorerContextMenu(props, ref) {
    const { identifiedConnection, deleteIdentifiedConnection, createNewIdentifiedConnection, } = props;
    const remove = () => deleteIdentifiedConnection?.();
    return (_jsxs(MenuContent, { ref: ref, children: [identifiedConnection && (_jsx(MenuContentItem, { onClick: remove, children: "Remove" })), !identifiedConnection && (_jsx(MenuContentItem, { onClick: createNewIdentifiedConnection, children: "Create a new connection for store" }))] }));
}));
export const IdentifiedConnectionsPerStoreExplorerItem = observer((props) => {
    const { identifiedConnection, currentRuntimeEditorTabState, isActive, isReadOnly, } = props;
    const editorStore = useEditorStore();
    const openConnection = () => currentRuntimeEditorTabState.openIdentifiedConnection(identifiedConnection);
    const deleteConnection = () => currentRuntimeEditorTabState.deleteIdentifiedConnection(identifiedConnection);
    const openNewConnectionModal = () => currentRuntimeEditorTabState.addIdentifiedConnection();
    // context menu
    const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] = useState(false);
    const onContextMenuOpen = () => setIsSelectedFromContextMenu(true);
    const onContextMenuClose = () => setIsSelectedFromContextMenu(false);
    return (_jsx(ContextMenu, { className: clsx('runtime-explorer__item', {
            'context-menu__trigger--on-menu-open': !isActive && isSelectedFromContextMenu,
        }, { 'runtime-explorer__item--active': isActive }), disabled: isReadOnly, content: _jsx(IdentifiedConnectionsPerStoreExplorerContextMenu, { identifiedConnection: identifiedConnection, deleteIdentifiedConnection: deleteConnection, createNewIdentifiedConnection: openNewConnectionModal }), menuProps: { elevation: 7 }, onOpen: onContextMenuOpen, onClose: onContextMenuClose, children: _jsxs("button", { className: "runtime-explorer__item__label runtime-explorer__item__label--simple", onClick: openConnection, tabIndex: -1, title: getConnectionTooltipText(identifiedConnection.connection, editorStore), children: [_jsx("div", { className: "runtime-explorer__item__label__icon", children: _jsx(PURE_ConnectionIcon, {}) }), _jsx("div", { className: "runtime-explorer__item__label__text", children: identifiedConnection.id })] }) }));
});
const getRuntimeExplorerTreeNodeIcon = (editorStore, node) => {
    if (node.data instanceof Runtime) {
        return _jsx(PURE_RuntimeIcon, {});
    }
    else if (node.data instanceof ModelStore) {
        return _jsx(PURE_ModelStoreIcon, {});
    }
    else if (node.data instanceof Connection) {
        return _jsx(PURE_ConnectionIcon, {});
    }
    return getElementIcon(node.data, editorStore);
};
const getRuntimeExplorerTreeNodeTooltipText = (node) => {
    if (node.data instanceof Runtime) {
        return ''; // number of mapping and stores
    }
    else if (node.data instanceof ModelStore) {
        return '';
    }
    else if (node.data instanceof Store) {
        /* do nothing */
    }
    else if (node.data instanceof Class) {
        // return `JSON model connection \u2022 Class ${connectionValue.class.path}`;
    }
    return undefined;
};
const RuntimeExplorerTreeNodeContainer = observer((props) => {
    const { node, level, stepPaddingInRem, onNodeSelect, innerProps } = props;
    const { runtimeEditorState, onNodeExpand } = innerProps;
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const editorStore = useEditorStore();
    const isExpandable = Boolean(node.childrenIds?.length);
    const nodeExpandIcon = isExpandable ? (node.isOpen ? (_jsx(ChevronDownIcon, {})) : (_jsx(ChevronRightIcon, {}))) : (_jsx("div", {}));
    const selectNode = () => onNodeSelect?.(node);
    const onExpandIconClick = () => onNodeExpand(node);
    // Selection
    const isActive = engineEditorState.isTreeNodeSelected(node);
    return (_jsx("div", { className: clsx('tree-view__node__container runtime-explorer__tree__node__container', { 'runtime-explorer__item--active': isActive }), onClick: selectNode, style: {
            paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1) + 0.5}rem`,
            display: 'flex',
        }, children: _jsxs("button", { className: "runtime-explorer__item__label", tabIndex: -1, title: getRuntimeExplorerTreeNodeTooltipText(node), children: [_jsx("div", { className: "tree-view__node__expand-icon", onClick: onExpandIconClick, children: nodeExpandIcon }), _jsx("div", { className: "runtime-explorer__item__label__icon", children: getRuntimeExplorerTreeNodeIcon(editorStore, node) }), node.data instanceof Runtime && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "runtime-explorer__item__label__text", children: [node.label, " ~"] }), _jsx("div", { className: "runtime-explorer__item__label__runtime__mapping__icon", children: _jsx(PURE_MappingIcon, {}) }), _jsx("div", { className: "runtime-explorer__item__label__runtime__mapping__text", children: engineEditorState.runtimeValue.mappings.length
                                ? engineEditorState.runtimeValue
                                    .mappings[0].value.name
                                : '(no mapping)' })] })), node.data instanceof Store && (_jsx("div", { className: "runtime-explorer__item__label__text", children: node.label })), node.data instanceof Class && (_jsx("div", { className: "runtime-explorer__item__label__text", children: node.label }))] }) }));
});
const RuntimeExplorer = observer((props) => {
    const { runtimeEditorState, isReadOnly } = props;
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const runtime = runtimeEditorState.runtime;
    const runtimeValue = engineEditorState.runtimeValue;
    const runtimeName = runtime instanceof RuntimePointer
        ? runtime.packageableRuntime.value.name
        : CUSTOM_LABEL;
    // explorer tree data
    const treeData = engineEditorState.explorerTreeData;
    const onNodeSelect = (node) => engineEditorState.onExplorerTreeNodeSelect(node);
    const onNodeExpand = (node) => engineEditorState.onExplorerTreeNodeExpand(node);
    const getTreeChildNodes = (node) => engineEditorState.getExplorerTreeChildNodes(node);
    // DnD
    const handleDropRuntimeSubElement = useCallback((item) => {
        const element = item.data.packageableElement;
        if (!isReadOnly) {
            if (element instanceof PackageableConnection) {
                engineEditorState.addIdentifiedConnection(new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), new ConnectionPointer(PackageableElementExplicitReference.create(element))));
            }
            else if (element instanceof Mapping) {
                engineEditorState.addMapping(element);
            }
        }
    }, [engineEditorState, isReadOnly, runtimeValue]);
    const [{ isRuntimeSubElementDragOver }, dropConnector] = useDrop(() => ({
        accept: [
            CORE_DND_TYPE.PROJECT_EXPLORER_CONNECTION,
            CORE_DND_TYPE.PROJECT_EXPLORER_MAPPING,
        ],
        drop: (item) => handleDropRuntimeSubElement(item),
        collect: (monitor) => ({
            isRuntimeSubElementDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropRuntimeSubElement]);
    useEffect(() => {
        engineEditorState.decorateRuntimeConnections();
        engineEditorState.reprocessCurrentTabState();
        engineEditorState.reprocessRuntimeExplorerTree();
        return () => engineEditorState.cleanUpDecoration();
    }, [engineEditorState, runtimeEditorState]);
    return (_jsxs(Panel, { className: "runtime-explorer", children: [_jsx(PanelHeader, { title: "runtime", children: _jsx("div", { className: "panel__header__title__content", children: runtimeName }) }), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isRuntimeSubElementDragOver, children: _jsx("div", { className: "panel__content__list", children: _jsx(TreeView, { components: {
                                TreeNodeContainer: RuntimeExplorerTreeNodeContainer,
                            }, treeData: treeData, onNodeSelect: onNodeSelect, getChildNodes: getTreeChildNodes, innerProps: {
                                isReadOnly,
                                runtimeEditorState,
                                onNodeExpand,
                            } }) }) }) })] }));
});
const IdentifiedConnectionEditor = observer((props) => {
    const { runtimeEditorState, currentRuntimeEditorTabState, connectionEditorState, identifiedConnection, isReadOnly, } = props;
    const applicationStore = useApplicationStore();
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const runtimeValue = engineEditorState.runtimeValue;
    // TODO: add runtime connection ID
    // connection pointer
    const isEmbeddedConnection = !(identifiedConnection.connection instanceof ConnectionPointer);
    const embeddedConnectionLabel = (_jsxs("div", { className: "runtime-connection-editor__connection-option--custom", children: [_jsx(CogIcon, {}), _jsx("div", { className: "runtime-connection-editor__connection-option--custom__label", children: CUSTOM_LABEL })] }));
    // only show custom connnection option when a connnection pointer is currently selected
    let connectionOptions = isEmbeddedConnection
        ? []
        : [{ label: embeddedConnectionLabel }];
    connectionOptions = connectionOptions.concat(currentRuntimeEditorTabState.packageableConnections.map((packageableConnection) => ({
        label: packageableConnection.path,
        value: packageableConnection,
    })));
    const selectedConnectionOption = identifiedConnection.connection instanceof ConnectionPointer
        ? {
            value: identifiedConnection.connection.packageableConnection.value,
            label: isEmbeddedConnection
                ? embeddedConnectionLabel
                : identifiedConnection.connection.packageableConnection.value
                    .path,
        }
        : null;
    const editorStore = useEditorStore();
    const onConnectionSelectionChange = (val) => {
        if (val.value === undefined) {
            let customConnection;
            try {
                customConnection =
                    currentRuntimeEditorTabState.createDefaultConnection();
            }
            catch (error) {
                assertErrorThrown(error);
                applicationStore.notificationService.notifyWarning(error.message);
                return;
            }
            const newIdentifiedConnection = new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), customConnection);
            runtime_addIdentifiedConnection(runtimeValue, newIdentifiedConnection, editorStore.changeDetectionState.observerContext);
            runtime_deleteIdentifiedConnection(runtimeValue, identifiedConnection);
            currentRuntimeEditorTabState.openIdentifiedConnection(newIdentifiedConnection);
        }
        else if (val.value instanceof PackageableConnection &&
            (!(identifiedConnection.connection instanceof ConnectionPointer) ||
                val.value !==
                    identifiedConnection.connection.packageableConnection.value)) {
            const connectionPointer = new ConnectionPointer(PackageableElementExplicitReference.create(val.value));
            const newIdentifiedConnection = new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), connectionPointer);
            runtime_addIdentifiedConnection(runtimeValue, newIdentifiedConnection, editorStore.changeDetectionState.observerContext);
            runtime_deleteIdentifiedConnection(runtimeValue, identifiedConnection);
            currentRuntimeEditorTabState.openIdentifiedConnection(newIdentifiedConnection);
        }
    };
    const visitConnection = () => {
        if (identifiedConnection.connection instanceof ConnectionPointer) {
            editorStore.graphEditorMode.openElement(identifiedConnection.connection.packageableConnection.value);
        }
    };
    return (_jsxs("div", { className: "runtime-connection-editor", children: [_jsxs("div", { className: "panel runtime-connection-editor__pointer", children: [_jsx(PanelHeader, { title: "runtime connection" }), _jsx(PanelContent, { children: _jsxs("div", { className: "runtime-connection-editor__connection-option", children: [_jsx("div", { className: "runtime-connection-editor__connection-option__label", children: _jsx(PURE_ConnectionIcon, {}) }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", disabled: isReadOnly, options: connectionOptions, onChange: onConnectionSelectionChange, value: selectedConnectionOption, darkMode: !applicationStore.layoutService
                                        .TEMPORARY__isLightColorThemeEnabled }), !isEmbeddedConnection && (_jsx("button", { className: "btn--dark btn--sm runtime-connection-editor__connection-option__visit-btn", onClick: visitConnection, tabIndex: -1, title: "See connection", children: _jsx(LongArrowRightIcon, {}) }))] }) })] }), _jsx("div", { className: "runtime-connection-editor__embedded", children: _jsx(ConnectionEditor, { connectionEditorState: connectionEditorState, disableChangingStore: true, isReadOnly: isReadOnly }) })] }));
});
const IdentifiedConnectionsPerStoreEditor = observer((props) => {
    const { isReadOnly, currentRuntimeEditorTabState, runtimeEditorState } = props;
    const isEmbeddedRuntime = runtimeEditorState.isEmbeddedRuntime;
    const connectionEditorState = currentRuntimeEditorTabState.getConnectionEditorState();
    const identifiedConnection = currentRuntimeEditorTabState.identifiedConnectionEditorState
        ?.idenfitiedConnection;
    // explorer
    const addNewConnection = () => currentRuntimeEditorTabState.addIdentifiedConnection();
    // DnD
    const handleDropConnection = useCallback((item) => {
        const element = item.data.packageableElement;
        if (!isReadOnly &&
            element instanceof PackageableConnection &&
            currentRuntimeEditorTabState.packageableConnections.includes(element)) {
            currentRuntimeEditorTabState.addIdentifiedConnection(element);
        }
    }, [currentRuntimeEditorTabState, isReadOnly]);
    const [{ isConnectionDragOver, dragItem }, dropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_CONNECTION],
        drop: (item) => handleDropConnection(item),
        collect: (monitor) => ({
            isConnectionDragOver: monitor.isOver({ shallow: true }),
            dragItem: monitor.getItem(),
        }),
    }), [handleDropConnection]);
    const canDropConnection = !isReadOnly &&
        dragItem instanceof ElementDragSource &&
        dragItem.data.packageableElement instanceof PackageableConnection &&
        currentRuntimeEditorTabState.packageableConnections.includes(dragItem.data.packageableElement);
    return (_jsx("div", { className: "runtime-store-connections-editor", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 300, minSize: 300, children: _jsxs(Panel, { className: "runtime-explorer", children: [_jsxs(PanelHeader, { children: [currentRuntimeEditorTabState instanceof
                                        IdentifiedConnectionsPerStoreEditorTabState && (_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "store" }), _jsx("div", { className: "panel__header__title__content", children: currentRuntimeEditorTabState.store.name })] })), currentRuntimeEditorTabState instanceof
                                        IdentifiedConnectionsPerClassEditorTabState && (_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "store" }), _jsx("div", { className: "panel__header__title__content", children: "ModelStore" }), _jsx("div", { className: "runtime-store-connections-editor__model-store__arrow-icon", children: _jsx(CaretRightIcon, {}) }), _jsx("div", { className: "runtime-store-connections-editor__model-store__class-icon", children: _jsx(PURE_ClassIcon, {}) }), _jsx("div", { className: "runtime-store-connections-editor__model-store__class-name", children: currentRuntimeEditorTabState.class.name })] })), _jsx(PanelHeaderActions, { children: _jsx(PanelHeaderActionItem, { disabled: isReadOnly, onClick: addNewConnection, title: "Add Connection...", children: _jsx(PlusIcon, {}) }) })] }), _jsx(ContextMenu, { className: "panel__content", disabled: isReadOnly, content: _jsx(IdentifiedConnectionsPerStoreExplorerContextMenu, { createNewIdentifiedConnection: addNewConnection }), menuProps: { elevation: 7 }, children: _jsxs(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isConnectionDragOver, children: [Boolean(currentRuntimeEditorTabState.identifiedConnections.length) && (_jsx("div", { className: "panel__content__list", children: currentRuntimeEditorTabState.identifiedConnections.map((rtConnection) => (_jsx(IdentifiedConnectionsPerStoreExplorerItem, { identifiedConnection: rtConnection, currentRuntimeEditorTabState: currentRuntimeEditorTabState, isActive: rtConnection === identifiedConnection, isReadOnly: isReadOnly }, rtConnection._UUID))) })), !currentRuntimeEditorTabState.identifiedConnections
                                            .length && (_jsx(BlankPanelPlaceholder, { text: "Add a connection", onClick: addNewConnection, clickActionType: "add", tooltipText: "Drop a connection to add it to the list, or click to add an embedded connection", isDropZoneActive: isEmbeddedRuntime ? undefined : canDropConnection, disabled: isReadOnly, previewText: "No connection" }))] }) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsxs(ResizablePanel, { children: [connectionEditorState && identifiedConnection && (_jsx(IdentifiedConnectionEditor, { runtimeEditorState: runtimeEditorState, currentRuntimeEditorTabState: currentRuntimeEditorTabState, connectionEditorState: connectionEditorState, identifiedConnection: identifiedConnection, isReadOnly: isReadOnly })), (!connectionEditorState || !identifiedConnection) && (_jsxs(Panel, { children: [_jsx(PanelHeader, { title: "runtime connection" }), _jsx(PanelContent, { children: _jsx(BlankPanelContent, { children: "No connection selected" }) })] }))] })] }) }));
});
const RuntimeMappingEditor = observer((props) => {
    const { runtimeEditorState, mappingRef, isReadOnly } = props;
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const editorStore = useEditorStore();
    const applicationStore = editorStore.applicationStore;
    const runtimeValue = engineEditorState.runtimeValue;
    const mappingOptions = editorStore.graphManagerState.graph.ownMappings
        .filter((m) => !runtimeValue.mappings.map((_m) => _m.value).includes(m))
        .map(buildElementOption);
    const filterOption = createFilter({
        ignoreCase: true,
        ignoreAccents: false,
        stringify: (option) => option.data.value.path,
    });
    const selectedMappingOption = {
        value: mappingRef.value,
        label: mappingRef.value.name,
    };
    const changeMapping = (val) => engineEditorState.changeMapping(mappingRef, val.value);
    const deleteMapping = () => engineEditorState.deleteMapping(mappingRef);
    const visitMapping = () => editorStore.graphEditorMode.openElement(mappingRef.value);
    return (_jsxs("div", { className: "panel__content__form__section__list__item--customized runtime-mapping-editor", children: [_jsx(CustomSelectorInput, { className: "runtime-mapping-editor__mapping", disabled: isReadOnly, options: mappingOptions, onChange: changeMapping, value: selectedMappingOption, placeholder: "Choose a class", filterOption: filterOption, darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled }), _jsx("button", { className: "btn--dark btn__icon--dark", onClick: visitMapping, tabIndex: -1, title: "Visit Mapping", children: _jsx(LongArrowRightIcon, {}) }), !isReadOnly && (_jsx("button", { className: "btn--dark btn__icon--dark btn--caution", disabled: runtimeValue.mappings.length < 2, onClick: deleteMapping, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] }));
});
const RuntimeGeneralEditor = observer((props) => {
    const { runtimeEditorState, isReadOnly } = props;
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const editorStore = useEditorStore();
    const runtime = runtimeEditorState.runtime;
    const runtimeValue = engineEditorState.runtimeValue;
    const isRuntimeEmbedded = !(runtime instanceof RuntimePointer);
    // mappings
    const mappings = editorStore.graphManagerState.graph.ownMappings.filter((mapping) => !runtimeValue.mappings.map((m) => m.value).includes(mapping));
    const allowAddingMapping = !isReadOnly && Boolean(mappings.length);
    const addMapping = () => {
        if (allowAddingMapping) {
            engineEditorState.addMapping(mappings[0]);
        }
    };
    const handleDropMapping = useCallback((item) => {
        const element = item.data.packageableElement;
        if (!isReadOnly &&
            // Have to be a mapping
            element instanceof Mapping &&
            // Must not be an already specified mapping
            !runtimeValue.mappings.map((m) => m.value).includes(element)) {
            engineEditorState.addMapping(element);
        }
    }, [engineEditorState, isReadOnly, runtimeValue.mappings]);
    const [{ isMappingDragOver }, dropConnector] = useDrop(() => ({
        accept: [CORE_DND_TYPE.PROJECT_EXPLORER_MAPPING],
        drop: (item) => handleDropMapping(item),
        collect: (monitor) => ({
            isMappingDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDropMapping]);
    return (_jsxs("div", { className: "panel runtime-explorer", children: [_jsx(PanelHeader, {}), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isMappingDragOver && !isReadOnly, children: _jsx("div", { className: "panel__content__form", children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Mappings" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Specifies the list of mappings covered by this runtime" }), _jsxs("div", { className: "panel__content__form__section__list", children: [runtimeValue.mappings.map((mappingRef) => (_jsx(RuntimeMappingEditor, { runtimeEditorState: runtimeEditorState, mappingRef: mappingRef, isReadOnly: isReadOnly || isRuntimeEmbedded }, mappingRef.value._UUID))), !isRuntimeEmbedded && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: !allowAddingMapping, tabIndex: -1, onClick: addMapping, title: "Add Mapping", children: "Add Value" }) }))] })] }) }) }) })] }));
});
const RuntimeEditorPanel = observer((props) => {
    const { runtimeEditorState, isReadOnly } = props;
    const engineEditorState = runtimeEditorState.runtimeValueEditorState;
    const currentRuntimeEditorTabState = engineEditorState.currentTabState;
    if (currentRuntimeEditorTabState instanceof
        IdentifiedConnectionsEditorTabState) {
        return (_jsx(IdentifiedConnectionsPerStoreEditor, { runtimeEditorState: runtimeEditorState, currentRuntimeEditorTabState: currentRuntimeEditorTabState, isReadOnly: isReadOnly }, runtimeEditorState.uuid));
    }
    else if (currentRuntimeEditorTabState instanceof RuntimeEditorRuntimeTabState) {
        return (_jsx(RuntimeGeneralEditor, { runtimeEditorState: runtimeEditorState, runtimeEditorTabState: currentRuntimeEditorTabState, isReadOnly: isReadOnly }, runtimeEditorState.uuid));
    }
    return _jsx("div", {}); // no need for splash screen since will always show at least a tab
});
export const RuntimeEditor = observer((props) => {
    const { runtimeEditorState, isReadOnly } = props;
    return (_jsx("div", { className: "runtime-editor", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 300, minSize: 300, children: _jsx(RuntimeExplorer, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx(RuntimeEditorPanel, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) })] }) }));
});
export const LakehouseRuntimeEditor = observer((props) => {
    const { runtimeEditorState, lakehouseRuntimeEditorState, isReadOnly } = props;
    const editorStore = runtimeEditorState.editorStore;
    const auth = useAuth();
    const applicationStore = editorStore.applicationStore;
    const lakehouseRuntime = lakehouseRuntimeEditorState.runtimeValue;
    // type
    const typeOptions = Object.values(LakehouseRuntimeType).map((type) => ({
        label: prettyCONSTName(type),
        value: type,
    }));
    const selectedType = {
        label: prettyCONSTName(lakehouseRuntimeEditorState.lakehouseRuntimeType),
        value: lakehouseRuntimeEditorState.lakehouseRuntimeType,
    };
    const onTypeChange = (val) => {
        if (val.value !== lakehouseRuntimeEditorState.lakehouseRuntimeType) {
            lakehouseRuntimeEditorState.setLakehouseRuntimeType(val.value);
        }
    };
    const environmentOptions = lakehouseRuntimeEditorState.envOptions;
    const onEnvironmentSelectionChange = (val) => {
        if (!val) {
            lakehouseRuntime.environment = undefined;
            return;
        }
        if (val.value !== lakehouseRuntime.environment) {
            lakehouseRuntime.environment = val.value;
        }
    };
    const handleWarehouseChange = (val) => {
        lakehouseRuntime_setWarehouse(lakehouseRuntime, val);
    };
    const selectedEnvironmentOption = lakehouseRuntime.environment
        ? {
            label: lakehouseRuntime.environment,
            value: lakehouseRuntime.environment,
        }
        : null;
    const connection = lakehouseRuntime.connectionPointer?.packageableConnection.value;
    const connectionOptions = editorStore.graphManagerState.usableConnections.map(buildElementOption);
    const selectedConnectionOption = connection
        ? { label: connection.path, value: connection }
        : null;
    const onConnectionSelectionChange = (val) => {
        if (val.value !== connection) {
            lakehouseRuntime.connectionPointer = new ConnectionPointer(PackageableElementExplicitReference.create(val.value));
        }
    };
    useEffect(() => {
        flowResult(lakehouseRuntimeEditorState.fetchLakehouseSummaries(auth.user?.access_token)).catch(applicationStore.alertUnhandledError);
    }, [
        applicationStore.alertUnhandledError,
        auth.user?.access_token,
        lakehouseRuntimeEditorState,
    ]);
    return (_jsx(_Fragment, { children: _jsx("div", { className: "data-product-editor", children: _jsxs("div", { className: "panel", children: [_jsx("div", { className: "panel__header", children: _jsxs("div", { className: "panel__header__title", children: [isReadOnly && (_jsx("div", { className: "uml-element-editor__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "panel__header__title__label", children: "lakehouse runtime" })] }) }), _jsxs("div", { className: "panel", style: { padding: '1rem', flex: 0 }, children: [_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Lakehouse Runtime Source" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: typeOptions, onChange: onTypeChange, value: selectedType, darkMode: !applicationStore.layoutService
                                                .TEMPORARY__isLightColorThemeEnabled }) })] }), lakehouseRuntimeEditorState.lakehouseRuntimeType ===
                                LakehouseRuntimeType.ENVIRONMENT ? (_jsxs(_Fragment, { children: [_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Environment" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: environmentOptions, onChange: onEnvironmentSelectionChange, value: selectedEnvironmentOption, darkMode: !applicationStore.layoutService
                                                        .TEMPORARY__isLightColorThemeEnabled }) })] }), _jsx(PanelFormTextField, { name: "Warehouse", value: lakehouseRuntime.warehouse, prompt: "Provide the warehouse", update: handleWarehouseChange, placeholder: "Enter warehouse" })] })) : (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Connection" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: connectionOptions, onChange: onConnectionSelectionChange, value: selectedConnectionOption, darkMode: !applicationStore.layoutService
                                                .TEMPORARY__isLightColorThemeEnabled }) })] }))] })] }) }) }));
});
export const PackageableRuntimeEditor = observer(() => {
    const editorStore = useEditorStore();
    const editorState = editorStore.tabManagerState.getCurrentEditorState(PackageableRuntimeEditorState);
    const isReadOnly = editorState.isReadOnly;
    const runtimeEditorState = editorState.runtimeEditorState;
    const engineState = runtimeEditorState.runtimeValueEditorState;
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.RUNTIME_EDITOR);
    return engineState instanceof LakehouseRuntimeEditorState ? (_jsx(LakehouseRuntimeEditor, { lakehouseRuntimeEditorState: engineState, isReadOnly: isReadOnly, runtimeEditorState: editorState.runtimeEditorState })) : (_jsx(RuntimeEditor, { runtimeEditorState: editorState.runtimeEditorState, isReadOnly: isReadOnly }));
});
export const EmbeddedRuntimeEditor = observer((props) => {
    const { runtimeEditorState, onClose, isReadOnly } = props;
    const applicationStore = useApplicationStore();
    const closeEditor = () => onClose();
    if (!runtimeEditorState) {
        return null;
    }
    return (_jsx(Dialog, { open: Boolean(runtimeEditorState), onClose: closeEditor, 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 embedded-runtime-editor", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { icon: _jsx(CogIcon, {}), title: "custom runtime" }), _jsx(ModalHeaderActions, { children: _jsx("button", { className: "modal__header__action", tabIndex: -1, onClick: closeEditor, children: _jsx(TimesIcon, {}) }) })] }), _jsx(ModalBody, { className: "modal__body--footless", children: _jsx(RuntimeEditor, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) })] }) }));
});
//# sourceMappingURL=RuntimeEditor.js.map