"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XExecutableTester = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importStar(require("react"));
const date_fns_1 = require("date-fns");
const lab_1 = require("@mui/lab");
const core_1 = require("@material-ui/core");
const styled_components_1 = tslib_1.__importDefault(require("styled-components"));
const StyledButton_1 = require("../BuildlingBlocks/StyledButton");
const ResetIcon_1 = require("../Icon/ResetIcon");
const RunIcon_1 = require("../Icon/RunIcon");
const TestResultData_1 = require("@appglue/common/dist/Common/Testing/TestResultData");
const BaseTestResultData_1 = require("@appglue/common/dist/Common/Testing/BaseTestResultData");
const TestContext_1 = require("./TestContext");
const ExecutionData_1 = require("@appglue/common/dist/Common/Data/ExecutionData/ExecutionData");
const AutoBind_1 = require("@appglue/common/dist/Common/AutoBind");
const OpenBlueIcon_1 = require("../Icon/OpenBlueIcon");
const DropdownBlueIcon_1 = require("../Icon/DropdownBlueIcon");
const EventLog_1 = require("@appglue/common/dist/Common/Event/EventLog");
const XDataDefOrObjectDefLayer_1 = require("../DataEditing/XDataDefOrObjectDefLayer");
const CloseGrayIcon_1 = require("../Icon/CloseGrayIcon");
const IFormHost_1 = require("@appglue/common/dist/Common/Execution/IFormHost");
const TestDisplayFactory_1 = require("./TestDisplayFactory");
const UIStyleConstants_1 = require("@appglue/common/dist/Common/UIStyleConstants");
const material_1 = require("@mui/material");
const DefineUnitTest_1 = require("./DefineUnitTest");
const UnitTestResultNode_1 = require("@appglue/common/dist/Common/UnitTesting/UnitTestResultNode");
const UnitTestConfiguration_1 = require("@appglue/common/dist/Common/UnitTesting/UnitTestConfiguration");
const FlowConfiguration_1 = require("@appglue/common/dist/Flow/FlowConfiguration");
const FlowEngine_1 = require("@appglue/common/dist/Flow/Engine/FlowEngine");
const AppGlueCorePlugins_1 = require("@appglue/common/dist/AppGlueCorePlugins");
function getNormalizedTitle(title) {
    return (title || "").replace(/_/g, " ");
}
class XExecutableTester extends react_1.Component {
    constructor(props) {
        super(props);
        this.state = {
            testcontext: new TestResultData_1.TestResultData(),
            value: undefined,
            data: props.startData ?? props.executable.getInputDefinition().getValueObject(),
            currentView: "UI",
            tabs: [
                { name: "UI", ui: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}) },
                {
                    name: "Events",
                    ui: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}),
                },
            ],
            openInputLayer: false,
        };
    }
    onStart(newdata) {
        if (!newdata) {
            this.setState({
                data: {},
            });
            return;
        }
        this.setState({
            data: newdata,
        });
        IFormHost_1.FormHost.defaultFormHost = undefined;
        try {
            if (this.props.executable instanceof FlowConfiguration_1.FlowConfiguration) {
                let promise = FlowEngine_1.FlowEngine.startFlow(AppGlueCorePlugins_1.AppGlueCorePlugins.UserContext.getCurrentUser(), this.props.executable, new ExecutionData_1.ExecutionData(newdata), this.state.testcontext);
                if (promise instanceof Promise) {
                    promise.then(() => {
                        // todo: check the result with currentView, because we can not finish and move to other tester.
                        this.forceUpdate();
                    });
                }
            }
            else {
                let promise = this.props.executable.run(new ExecutionData_1.ExecutionData(newdata), this.state.testcontext);
                if (promise instanceof Promise) {
                    promise.then(() => {
                        // todo: check the result with currentView, because we can not finish and move to other tester.
                        this.forceUpdate();
                    });
                }
            }
        }
        catch (e) { }
        if (this.state.testcontext.items.length > 0) {
            this.onSelect(this.state.testcontext.items[this.state.testcontext.items.length - 1]);
        }
    }
    onReset(event) {
        event.stopPropagation();
        this.setState({
            testcontext: new TestResultData_1.TestResultData(),
            value: undefined,
        });
    }
    onSelect(selecteditem) {
        let tabs = [
            { name: "UI", ui: TestDisplayFactory_1.TestDisplayFactory.renderTestDisplay(selecteditem) ?? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}) },
            {
                name: "Events",
                ui: ((0, jsx_runtime_1.jsx)(EventsRender, { children: (selecteditem?.logs || []).map((log) => ((0, jsx_runtime_1.jsxs)(EventRender, { type: log.type, children: [(0, date_fns_1.format)(log.when, "dd.MM.yy HH:mm:ss.sss"), ": ", log.message] }, log.when.getTime()))) })),
            },
        ];
        if (selecteditem && TestDisplayFactory_1.TestDisplayFactory.renderTabs(selecteditem)) {
            tabs = TestDisplayFactory_1.TestDisplayFactory.renderTabs(selecteditem);
        }
        this.setState({ value: selecteditem, tabs, currentView: tabs[0].name });
    }
    renderTree() {
        return ((0, jsx_runtime_1.jsxs)(TesterTreeView, { children: [this.state.testcontext.items.length === 0 && ((0, jsx_runtime_1.jsx)(TesterStatus, { children: "Welcome to the debugging system. Enter first data and push on \"Play\" to starting testing" })), this.state.testcontext.items
                    .sort((a, b) => {
                    if (a.when > b.when)
                        return -1;
                    return 1;
                })
                    .map((item, idx) => ((0, jsx_runtime_1.jsx)(TesterTreeItem, { data: this.state.data, item: item, onSelect: this.onSelect, builderName: this.props.builderName }, `${idx}-${item.when.getTime()}`)))] }));
    }
    onChangeView(_event, value) {
        this.setState({
            currentView: value,
        });
    }
    onOpenInputLayer(event) {
        event.stopPropagation();
        this.setState({
            openInputLayer: true,
        });
    }
    render() {
        // render side tree
        // render run button
        // render ui for parameters to be gathered
        // when its run, find the first node with a ui and render the ui to the right
        return ((0, jsx_runtime_1.jsx)(TestContext_1.TestContext.Provider, { value: this.state.value, children: (0, jsx_runtime_1.jsx)(lab_1.TabContext, { value: this.state.currentView, children: (0, jsx_runtime_1.jsxs)(Render, { children: [(0, jsx_runtime_1.jsxs)(TesterLeftSide, { children: [(0, jsx_runtime_1.jsxs)(TesterControls, { children: [(0, jsx_runtime_1.jsx)("div", { children: "Debugging" }), (0, jsx_runtime_1.jsxs)(TestActions, { children: [(0, jsx_runtime_1.jsx)(StyledButton_1.StyledButton, { endIcon: (0, jsx_runtime_1.jsx)(ResetIcon_1.ResetIcon, {}), size: "small", onClick: this.onReset, children: "Reset" }), (0, jsx_runtime_1.jsxs)(RunButton, { "data-testid": "XExecutableTester-play", onClick: this.onOpenInputLayer, children: ["Play", (0, jsx_runtime_1.jsx)(RunIcon_1.RunIcon, {})] }), (0, jsx_runtime_1.jsx)(XDataDefOrObjectDefLayer_1.XDataDefOrObjectDefLayer, { data: this.props.executable.getInputDefinition(), value: this.state.data, open: this.state.openInputLayer, renderTitle: () => ((0, jsx_runtime_1.jsxs)(RenderInputLayerTitle, { children: ["Test Data", (0, jsx_runtime_1.jsx)(CloseButton, { onClick: (event) => {
                                                                    event.stopPropagation();
                                                                    this.setState({
                                                                        openInputLayer: false,
                                                                    });
                                                                }, children: (0, jsx_runtime_1.jsx)(CloseGrayIcon_1.CloseGrayIcon, {}) })] })), updateCallback: (newValue) => {
                                                        this.setState({
                                                            openInputLayer: false,
                                                        });
                                                        this.onStart(newValue);
                                                    }, doneButtonTitle: "Run" })] })] }), this.renderTree()] }), (0, jsx_runtime_1.jsxs)(TesterRender, { children: [(0, jsx_runtime_1.jsx)(lab_1.TabList, { onChange: this.onChangeView, color: "primary", children: this.state.tabs.map((tab) => ((0, jsx_runtime_1.jsx)(core_1.Tab, { value: tab.name, label: tab.name }, tab.name))) }), (0, jsx_runtime_1.jsx)(BuilderRender, { children: this.state.tabs.map((tab, idx) => ((0, jsx_runtime_1.jsx)(lab_1.TabPanel, { style: { height: "100%" }, value: tab.name, children: tab.ui }, idx))) })] })] }) }) }));
    }
}
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "onStart", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "onReset", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "onSelect", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "renderTree", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "onChangeView", null);
tslib_1.__decorate([
    AutoBind_1.AutoBind
], XExecutableTester.prototype, "onOpenInputLayer", null);
exports.XExecutableTester = XExecutableTester;
const TesterTreeItem = (props) => {
    const [iscollapsed, setIsCollapsed] = (0, react_1.useState)(true);
    const [defineTest, setDefineTest] = (0, react_1.useState)(false);
    const testContext = react_1.default.useContext(TestContext_1.TestContext);
    const isclickable = !!TestDisplayFactory_1.TestDisplayFactory.renderTestDisplay(props.item);
    const subitems = props.item.items;
    const haschildren = !!subitems.find((item) => item instanceof BaseTestResultData_1.BaseTestResultData);
    const onSelect = (item) => {
        props.onSelect(item);
    };
    const onToggle = (event) => {
        event.stopPropagation();
        if (haschildren) {
            setIsCollapsed(!iscollapsed);
        }
    };
    const [unitTest, setUnitTest] = (0, react_1.useState)();
    (0, react_1.useEffect)(() => {
        setUnitTest(new UnitTestConfiguration_1.UnitTestConfiguration(UnitTestResultNode_1.UnitTestResultNode.createResultNode(props.item), props.data));
    }, [props.item]);
    return ((0, jsx_runtime_1.jsxs)(TesterSection, { "data-testid": `treeitem-${props.item.type}`, onClick: (event) => {
            event.stopPropagation();
            if (isclickable) {
                onSelect(props.item);
            }
            else if (subitems.length > 0) {
                let firstitem = subitems.find((it) => it instanceof BaseTestResultData_1.BaseTestResultData);
                if (firstitem) {
                    onSelect(firstitem);
                }
                setIsCollapsed(false);
            }
        }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { display: "flex", flexDirection: "row", justifyContent: "space-between", paddingTop: "4px", paddingBottom: "4px", paddingLeft: "8px", paddingRight: "8px", bgcolor: testContext === props.item ? UIStyleConstants_1.UIStyleConstants.BLUE_VERY_LIGHT_COLOR : UIStyleConstants_1.UIStyleConstants.WHITE_COLOR, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { display: "flex", flexDirection: "row", children: [(0, jsx_runtime_1.jsx)(ExpandIconButton, { visible: haschildren, onClick: onToggle, children: iscollapsed ? (0, jsx_runtime_1.jsx)(OpenBlueIcon_1.OpenBlueIcon, {}) : (0, jsx_runtime_1.jsx)(DropdownBlueIcon_1.DropdownBlueIcon, {}) }), (0, jsx_runtime_1.jsxs)(TestedItemTitle, { children: [getNormalizedTitle(props.item.type), " (", props.item.getDuration(), ")", props.item.isShowResult && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), "Result: ", props.item.result] }))] })] }), testContext === props.item && (0, jsx_runtime_1.jsx)(material_1.Link, { onClick: () => setDefineTest(true), children: "+ Unit Test" })] }), haschildren && ((0, jsx_runtime_1.jsx)(core_1.Collapse, { in: !iscollapsed, children: (0, jsx_runtime_1.jsx)(TesterSectionBody, { children: subitems
                        .filter((i) => {
                        return !i.hidden;
                    })
                        .map((subi, index) => {
                        if (subi instanceof BaseTestResultData_1.BaseTestResultData) {
                            return ((0, jsx_runtime_1.jsx)(TesterTreeItem, { item: subi, onSelect: props.onSelect, builderName: props.builderName, data: props.data }, `${index}_${subi.when.getTime()}`));
                        }
                        return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, {}, `${index}_${subi.when.getTime()}`);
                    }) }) })), unitTest && ((0, jsx_runtime_1.jsx)(DefineUnitTest_1.DefineUnitTest, { open: defineTest, onClose: () => setDefineTest(false), onTestSave: () => {
                    if (props.saveUnitTest && unitTest)
                        props.saveUnitTest(unitTest);
                    setDefineTest(false);
                }, unitTest: unitTest }))] }));
};
const TesterSectionBody = styled_components_1.default.div `
    padding-left: 8px;
`;
const ExpandIconButton = styled_components_1.default.div `
    width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;

    visibility: ${(props) => (props.visible ? "visible" : "hidden")};
`;
const TesterRender = styled_components_1.default.div `
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;

    overflow: hidden;

    padding: 12px 16px;

    flex: 1;

    .MuiTabs-fixed {
        display: flex;
        align-items: center;
    }

    .MuiTabs-flexContainer {
        background: #fcfcfe;
        border: 1px solid rgba(39, 41, 50, 0.2);
        box-sizing: border-box;
        border-radius: 4px;
    }

    .MuiTabs-indicator {
        display: none;
    }

    .MuiTab-root {
        min-width: 60px;
        min-height: 0;

        //styleName: text/Inter Regular 12px;

        font-size: 12px;
        font-style: normal;
        font-weight: 400;
        line-height: 17px;
        letter-spacing: 0px;
        text-align: center;

        color: #272932;

        &.Mui-selected {
            background: #4050a6;
            color: #fff;
        }
    }
`;
const TesterLeftSide = styled_components_1.default.div `
    position: relative;
    display: flex;
    flex-direction: column;

    overflow: hidden;

    padding: 0 24px;
    border-right: solid 1px rgba(39, 41, 50, 0.05);

    background: #fff;

    min-width: 425px;
`;
const TesterTreeView = styled_components_1.default.div `
    display: flex;
    flex-direction: column;
    width: 375px;

    border: 1px solid rgba(39, 41, 50, 0.2);

    background: #fcfcfe;

    box-sizing: border-box;
    border-radius: 4px;

    padding: 8px 12px;

    flex: 1;
    overflow: auto;
`;
const BuilderRender = styled_components_1.default.div `
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: auto;
`;
const TesterControls = styled_components_1.default.div `
    padding: 8px 20px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;

    font-size: 16px;
    font-style: normal;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: 0em;
    text-align: left;

    color: #272932;

    width: 375px;
`;
const TestActions = styled_components_1.default.div `
    display: flex;
    flex-direction: row;
`;
const TesterStatus = styled_components_1.default.div `
    padding: 4px 8px;

    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: 17px;
    letter-spacing: 0px;
    text-align: left;
    color: #606881;
`;
const TestedItemTitle = styled_components_1.default.div `
    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: 17px;
    letter-spacing: 0px;
    text-align: left;
    color: #606881;
`;
const TesterSection = styled_components_1.default.div `
    cursor: pointer;
`;
const EventsRender = styled_components_1.default.div `
    display: flex;
    flex-direction: column;
`;
const EventRender = styled_components_1.default.div `
    color: ${(props) => (props.type === EventLog_1.EventLogType.ERROR ? UIStyleConstants_1.UIStyleConstants.RED_COLOR : "rgb(39, 41, 50)")};
`;
const RunButton = styled_components_1.default.div `
    display: flex;
    align-items: center;

    font-style: normal;
    font-weight: 500;
    font-size: 12px;
    line-height: 18px;
    color: #272932;

    padding: 6px 12px;
    position: relative;

    cursor: pointer;

    &:hover {
        background-color: rgba(0, 0, 0, 0.04);
    }

    & > img {
        margin-right: -2px;
        margin-left: 8px;
    }
`;
const Render = styled_components_1.default.div `
    display: flex;
    width: 100%;
    height: 100%;
    flex-direction: row;

    background: rgba(64, 80, 166, 0.05);
    overflow: hidden;
`;
const RenderInputLayerTitle = styled_components_1.default.div `
    position: relative;

    font-size: 18px;
    font-style: normal;
    font-weight: 600;
    line-height: 30px;

    maring-bottom: 15px;
`;
const CloseButton = styled_components_1.default.div `
    width: 24px;
    height: 24px;

    cursor: pointer;

    position: absolute;
    right: 0;
    top: 50%;

    transform: translateY(-50%);
`;
//# sourceMappingURL=XExecutableTester.js.map