/*
 * Copyright 2022 The Kubernetes Authors
 *
 * 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.
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import Debug from 'debug';
import React from 'react';
import { encodeComponent, pexecInCurrentTab } from '@kui-shell/core';
import { Tree, Graph, Choices, Memoizer } from 'madwizard';
import { TreeView } from '@patternfly/react-core/dist/esm/components/TreeView';
import Icons from '../../../spi/Icons';
import Markdown from '../../Markdown';
const ReactCommentary = React.lazy(() => import('../../Commentary').then(_ => ({ default: _.ReactCommentary })));
import '../../../../../web/scss/components/Tree/_index.scss';
import '../../../../../web/scss/components/Wizard/Imports.scss';
const debug = Debug('plugins/plugin-client-common/components/Content/Markdown/Imports');
class ReactUI {
    markdown(body) {
        return React.createElement(Markdown, { nested: true, source: body });
    }
    ask() {
        return Promise.resolve({});
    }
    span(content, ...decorations) {
        if (decorations.length === 0) {
            return content;
        }
        else {
            const className = decorations
                .map(decoration => decoration === 'blue'
                ? 'color-base0D'
                : decoration === 'red'
                    ? 'color-base08'
                    : decoration === 'magenta'
                        ? 'color-base0E'
                        : decoration === 'cyan'
                            ? 'color-base0C'
                            : decoration === 'yellow'
                                ? 'color-base09'
                                : decoration === 'dim'
                                    ? 'sub-text'
                                    : '')
                .filter(Boolean)
                .join(' ');
            if (decorations.includes('bold')) {
                return React.createElement("strong", { className: className }, content);
            }
            else {
                return React.createElement("span", { className: className }, content);
            }
        }
    }
    code(body) {
        return (React.createElement("pre", null,
            React.createElement("code", null, body)));
    }
    icon(cls) {
        return React.createElement(Icons, { className: "kui--dependence-tree-subtask--icon", icon: cls });
    }
    statusToIcon(status) {
        switch (status) {
            case 'success':
                return React.createElement(Icons, { className: "pf-m-success", icon: "Checkmark" });
        }
    }
    title(title, status) {
        if (Array.isArray(title)) {
            return (React.createElement(React.Fragment, null, title.map((_, idx, A) => (React.createElement("span", { key: idx },
                this.title(_, status),
                idx < A.length - 1 ? ' ' : '')))));
        }
        else if (status === 'error') {
            return React.createElement("span", { className: "red-text" }, title);
        }
        else {
            return title;
        }
    }
    open(filepath) {
        return (React.createElement("button", { className: "kui--tree-action pf-c-button pf-m-plain", onClick: () => {
                debug('drilling down to notebook', filepath);
                pexecInCurrentTab(`replay ${encodeComponent(filepath)}`, undefined, true, true);
            } },
            React.createElement(Icons, { icon: "Info" })));
    }
}
class Imports extends React.PureComponent {
    constructor(props) {
        super(props);
        this.memos = new Memoizer();
        this.onChoice = ({ choices }) => this.init(this.props, choices.clone());
        this.onValidate = (id, status) => {
            setTimeout(() => this.setState(curState => {
                const codeBlockStatus = Object.assign({}, curState.codeBlockStatus, { [id]: status });
                const { data } = this.computeTreeModel(curState.imports, codeBlockStatus, false);
                return { data, codeBlockStatus };
            }));
        };
        this.state = {
            data: null,
            imports: undefined,
            choices: props.choices,
            codeBlockStatus: undefined
        };
    }
    init(props, useTheseChoices) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const choices = useTheseChoices || props.choices || Choices.newChoiceState('default');
                if (!useTheseChoices && !props.choices) {
                    choices.onChoice(this.onChoice);
                }
                const newGraph = yield Graph.compile(props.imports, choices, this.memos, undefined, 'sequence', props.title, props.description);
                this.setState(state => {
                    try {
                        const noChange = state && Graph.sameGraph(state.imports, newGraph);
                        const imports = noChange ? state.imports : Graph.order(newGraph);
                        const codeBlockStatus = state ? this.state.codeBlockStatus : {};
                        const data = noChange ? state.data : this.computeTreeModel(imports, codeBlockStatus).data;
                        return noChange
                            ? null
                            : {
                                data,
                                choices,
                                imports,
                                error: undefined,
                                codeBlockStatus
                            };
                    }
                    catch (error) {
                        console.error(error);
                        return Object.assign({}, state, { error });
                    }
                });
            }
            catch (error) {
                console.error(error);
                this.setState({ error });
            }
        });
    }
    static getDerivedStateFromError(error) {
        console.error(error);
        return { error };
    }
    componentDidCatch(error, errorInfo) {
        console.error('catastrophic error in Imports', error, errorInfo);
    }
    componentDidMount() {
        this.computeTreeModelIfNeeded();
    }
    componentWillUnmount() {
        this.state.choices.offChoice(this.onChoice);
    }
    componentDidUpdate() {
        if (!this.state.error) {
            this.computeTreeModelIfNeeded();
        }
    }
    /** Compute or re-compute tree model */
    computeTreeModelIfNeeded() {
        if (!this.state.data) {
            this.init(this.props);
        }
    }
    computeTreeModel(imports = this.state.imports, status = this.state.codeBlockStatus, doValidate = true) {
        if (this.state.error) {
            return;
        }
        try {
            return {
                data: new Tree.Treeifier(new ReactUI(), status, doValidate && this.validate.bind(this)).toTree(imports)
            };
        }
        catch (error) {
            console.error(error);
            this.setState({ error });
        }
    }
    validate(props) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const status = this.state.codeBlockStatus ? this.state.codeBlockStatus[props.id] : 'blank';
                if (props.validate && status !== 'in-progress' && status !== 'success') {
                    try {
                        this.onValidate(props.id, 'in-progress');
                        // emitLinkUpdate(this.props.codeBlockId, 'in-progress')
                        yield pexecInCurrentTab(props.validate.toString(), undefined, true, true);
                        this.onValidate(props.id, 'success');
                        // emitLinkUpdate(this.props.codeBlockId, 'success')
                    }
                    catch (err) {
                        this.onValidate(props.id, 'blank');
                        // this.setState({ status: 'blank' })
                        // emitLinkUpdate(this.props.codeBlockId, 'blank')
                    }
                }
            }
            catch (error) {
                console.error(error);
                this.setState({ error });
            }
        });
    }
    render() {
        if (this.state.error) {
            return 'Internal Error';
        }
        return !this.state.data ? (React.createElement(React.Fragment, null)) : (React.createElement(TreeView, { className: "kui--dependence-tree kui--tree", hasGuides: true, data: this.state.data }));
    }
}
/* type LabelWithStatusProps = { label?: string; status: Status }

class LabelWithStatus extends React.PureComponent<LabelWithStatusProps> {
  private get status() {
    return this.props.status || 'blank'
  }

  private icon() {
    const icon = this.status === 'in-progress' ? <Spinner /> : statusToIcon(this.status)

    // make sure not to include any wrappers if we have no actual content
    return icon && <span className={statusToClassName(this.status) + ' kui--validator small-left-pad'}>{icon}</span>
  }

  public render() {
    const icon = this.icon()
    const { label } = this.props

    // make sure not to include any wrappers if we have no actual content
    return (
      (label || icon) && (
        <span className="kui--tree-leaf-label no-wrap">
          {label}
          {icon}
        </span>
      )
    )
  }
} */
export default function guidebookImports(props) {
    return (React.createElement(ReactCommentary, null,
        React.createElement("div", { className: "padding-content marked-content page-content", "data-is-nested": true },
            React.createElement(Imports, Object.assign({}, props)))));
}
//# sourceMappingURL=Imports.js.map