import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
import { useCallback, useEffect, useState } from 'react';
import { KernelIndicator, useJupyterReactStore, } from '@datalayer/jupyter-react';
import { ISanitizer } from '@jupyterlab/apputils';
import { IMarkdownParser } from '@jupyterlab/rendermime';
import { ActionList, ActionMenu, Box, Button, Tooltip } from '@primer/react';
import { CloudIcon, EyeIcon, UnfoldIcon } from '@primer/octicons-react';
import { BrowserIcon, PlusIcon } from '@datalayer/icons-react';
import { ArtifactIcon } from '../../components/icons/index.js';
import { RuntimeLauncherDialog } from '../../components/runtimes/index.js';
import { useRuntimesStore } from '../../state/index.js';
/**
 * Cause to open the new runtime dialog.
 */
var RuntimeDialogCause;
(function (RuntimeDialogCause) {
    /**
     * Don't open.
     */
    RuntimeDialogCause[RuntimeDialogCause["None"] = 0] = "None";
    /**
     * Launch a new runtime.
     */
    RuntimeDialogCause[RuntimeDialogCause["New"] = 1] = "New";
    /**
     * Transfer the state from the current runtime to a new runtime.
     */
    RuntimeDialogCause[RuntimeDialogCause["Transfer"] = 2] = "Transfer";
})(RuntimeDialogCause || (RuntimeDialogCause = {}));
/**
 * Runtime simple picker component.
 */
export function RuntimeSimplePicker(props) {
    const { assignRuntime, sessionConnection, browserRuntimeAvailable = true, } = props;
    const { runtimeModels, multiServiceManager } = useRuntimesStore();
    const jupyterReactStore = useJupyterReactStore();
    const jupyterLabAdapter = jupyterReactStore.jupyterLabAdapter;
    const [runtimeLocation, setRuntimeLocation] = useState();
    const [luminoServices, setLuminoServices] = useState({});
    const [dialogCause, setDialogCause] = useState(RuntimeDialogCause.None);
    const [status, setStatus] = useState('');
    useEffect(() => {
        if (sessionConnection) {
            function onStatusChanged(connection) {
                setStatus(`Runtime ${connection.kernel?.connectionStatus} - Status: ${connection.kernel?.status}`);
            }
            onStatusChanged(sessionConnection);
            sessionConnection?.statusChanged.connect(onStatusChanged);
            sessionConnection?.connectionStatusChanged.connect(onStatusChanged);
            return () => {
                sessionConnection?.statusChanged.disconnect(onStatusChanged);
                sessionConnection?.connectionStatusChanged.disconnect(onStatusChanged);
            };
        }
        else {
            setStatus('No kernel');
        }
    }, [sessionConnection]);
    const refreshRemoteKernels = useCallback(async () => {
        if (multiServiceManager?.remote?.runtimesManager) {
            await multiServiceManager.remote.runtimesManager.refresh();
        }
    }, [multiServiceManager?.remote?.runtimesManager]);
    const handleLaunchRemoteKernel = useCallback(() => {
        setDialogCause(RuntimeDialogCause.New);
    }, []);
    const handleCloseDialog = useCallback((runtimeDesc) => {
        if (runtimeDesc) {
            switch (dialogCause) {
                case RuntimeDialogCause.New:
                    refreshRemoteKernels().then(() => {
                        setRuntimeLocation('remote');
                        assignRuntime({
                            runtimeDesc,
                            runtimeModel: multiServiceManager?.remote?.runtimesManager
                                .get()
                                .find(model => model.id === runtimeDesc.kernelId),
                        });
                    });
                    break;
                case RuntimeDialogCause.Transfer:
                    setRuntimeLocation('remote');
                    assignRuntime({ runtimeDesc, transferState: true });
                    break;
            }
        }
        setDialogCause(RuntimeDialogCause.None);
    }, [refreshRemoteKernels, multiServiceManager?.remote, dialogCause]);
    useEffect(() => {
        if (jupyterLabAdapter) {
            Promise.all([
                jupyterLabAdapter.jupyterLab.resolveOptionalService(IMarkdownParser),
                jupyterLabAdapter.jupyterLab.resolveOptionalService(ISanitizer),
            ]).then(services => {
                setLuminoServices({
                    [IMarkdownParser.name]: services[0],
                    [ISanitizer.name]: services[1],
                });
            });
        }
        else {
            setLuminoServices({});
        }
    }, [jupyterLabAdapter]);
    return (_jsxs(_Fragment, { children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { leadingVisual: () => {
                            switch (runtimeLocation) {
                                case 'browser':
                                    return _jsx(BrowserIcon, {});
                                case 'remote':
                                    return _jsx(CloudIcon, {});
                                case undefined:
                                    return _jsx(EyeIcon, {});
                            }
                            return _jsx(ArtifactIcon, { type: "runtime" });
                        }, trailingVisual: () => sessionConnection ? (_jsx(Box, { sx: { paddingTop: '5px' }, children: _jsx(KernelIndicator, { kernel: sessionConnection.kernel }) })) : (_jsx(_Fragment, {})), size: "small", variant: "invisible", children: _jsx(Tooltip, { text: status, direction: "s", children: _jsx(Button, { variant: "invisible", size: "small", children: sessionConnection?.kernel?.name ?? 'Runtimes' }) }) }), _jsx(ActionMenu.Overlay, { width: "medium", children: _jsxs(ActionList, { selectionVariant: "single", showDividers: true, children: [_jsxs(ActionList.Group, { children: [_jsxs(ActionList.Item, { selected: runtimeLocation === undefined &&
                                                sessionConnection === undefined, onSelect: () => {
                                                setRuntimeLocation(undefined);
                                                assignRuntime({ runtimeDesc: undefined });
                                            }, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(EyeIcon, {}) }), "Viewer", _jsx(ActionList.Description, { variant: "block", children: "A simple Notebook Viewer without Runtime." })] }), browserRuntimeAvailable && (_jsxs(ActionList.Item, { selected: runtimeLocation === 'browser', onSelect: () => {
                                                setRuntimeLocation('browser');
                                                assignRuntime({
                                                    runtimeDesc: {
                                                        name: 'pyodide',
                                                        location: 'browser',
                                                        language: 'python',
                                                    },
                                                });
                                            }, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(BrowserIcon, {}) }), "Browser Runtime", _jsx(ActionList.Description, { variant: "block", children: "A Browser Runtime based on Pyodide." })] }))] }), runtimeModels.length > 0 && (_jsxs(ActionList.Group, { children: [_jsx(ActionList.GroupHeading, { children: "Cloud Runtimes" }), runtimeModels.map(kernelModel => {
                                            return (_jsxs(ActionList.Item, { selected: sessionConnection?.kernel?.id === kernelModel.id, onSelect: () => {
                                                    setRuntimeLocation('remote');
                                                    assignRuntime({
                                                        runtimeDesc: {
                                                            name: kernelModel.environment_name,
                                                            language: '',
                                                            location: 'remote',
                                                            displayName: kernelModel.given_name,
                                                            kernelId: kernelModel.id,
                                                            burningRate: kernelModel.burning_rate,
                                                            podName: kernelModel.pod_name,
                                                        },
                                                        runtimeModel: kernelModel,
                                                    });
                                                }, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(ArtifactIcon, { type: "runtime" }) }), kernelModel.given_name, _jsx(ActionList.Description, { variant: "block", children: kernelModel.environment_name })] }, kernelModel.id));
                                        })] })), _jsx(ActionList.Divider, {}), _jsxs(ActionList.Group, { children: [_jsxs(ActionList.Item, { selected: false, onSelect: handleLaunchRemoteKernel, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(PlusIcon, {}) }), "Launch a new Runtime\u2026"] }), _jsxs(ActionList.Item, { disabled: runtimeLocation !== 'browser', selected: false, onSelect: () => {
                                                setDialogCause(RuntimeDialogCause.Transfer);
                                            }, title: "Transfer the state of the current Runtime to a new Remote Runtime.", children: [_jsx(ActionList.LeadingVisual, { children: _jsx(UnfoldIcon, {}) }), "Transfer state to a new Runtime\u2026"] })] })] }) })] }), multiServiceManager?.remote && dialogCause > 0 && (_jsx(RuntimeLauncherDialog, { dialogTitle: dialogCause === RuntimeDialogCause.Transfer
                    ? 'Switch to a new Cloud Runtime'
                    : undefined, manager: multiServiceManager.remote, onSubmit: handleCloseDialog, markdownParser: luminoServices[IMarkdownParser.name], sanitizer: luminoServices[ISanitizer.name], startRuntime: dialogCause === RuntimeDialogCause.Transfer
                    ? 'defer'
                    : dialogCause === RuntimeDialogCause.New }))] }));
}
