"use strict";
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());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NestiaEditorIframe = NestiaEditorIframe;
const jsx_runtime_1 = require("react/jsx-runtime");
const material_1 = require("@mui/material");
const sdk_1 = __importDefault(require("@stackblitz/sdk"));
const js_yaml_1 = require("js-yaml");
const react_1 = __importDefault(require("react"));
const NestiaEditorComposer_1 = require("./internal/NestiaEditorComposer");
function NestiaEditorIframe(props) {
    const [id] = react_1.default.useState(`reactia-editor-div-${Math.random().toString().substring(2)}`);
    const [step, setStep] = react_1.default.useState(0);
    const [fetchError, setFetchError] = react_1.default.useState(null);
    const [operations, setOperationCount] = react_1.default.useState({});
    const [composerError, setComposerError] = react_1.default.useState(null);
    react_1.default.useEffect(() => {
        (() => __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            // LOADING OPENAPI DOCUMENTS
            setStep(0);
            const document = typeof props.swagger === "string"
                ? yield getDocument(props.swagger)
                : props.swagger;
            if (typeof document === "string") {
                setFetchError(document);
                return;
            }
            else
                setOperationCount(aggregateOperation(document));
            // GENERATING SOFTWARE DEVELOPMENT KIT
            setStep(1);
            const result = yield (() => __awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c, _d, _e;
                try {
                    return yield NestiaEditorComposer_1.NestiaEditorComposer[(_a = props.mode) !== null && _a !== void 0 ? _a : "sdk"]({
                        document,
                        keyword: (_b = props.keyword) !== null && _b !== void 0 ? _b : true,
                        simulate: (_c = props.simulate) !== null && _c !== void 0 ? _c : true,
                        e2e: (_d = props.e2e) !== null && _d !== void 0 ? _d : true,
                        package: (_e = props.package) !== null && _e !== void 0 ? _e : "@ORGANIZATION/PROJECT",
                    });
                }
                catch (exp) {
                    return {
                        success: false,
                        errors: exp,
                        data: undefined,
                    };
                }
            }))();
            if (result.success === false) {
                setComposerError(result.errors);
                return;
            }
            // COMPOSING STACKBLITZ PROJECT
            setStep(2);
            sdk_1.default.embedProject(id, {
                title: (_b = (_a = document.info) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : "Nestia Editor",
                template: "node",
                files: result.data.files,
            }, {
                width: "100%",
                height: "100%",
                openFile: result.data.openFile,
                startScript: result.data.startScript, // no problem
            });
        }))().catch((exp) => {
            console.error("unknown error", exp);
        });
    }, []);
    return ((0, jsx_runtime_1.jsx)("div", { id: id, style: {
            width: "100%",
            height: "100%",
            overflow: "hidden",
        }, children: (0, jsx_runtime_1.jsxs)("div", { style: {
                padding: 25,
                overflow: "auto",
            }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h4", children: "Nestia Editor" }), (0, jsx_runtime_1.jsx)("hr", {}), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsxs)(material_1.Stepper, { activeStep: step, orientation: "vertical", nonLinear: true, children: [(0, jsx_runtime_1.jsxs)(material_1.Step, { children: [(0, jsx_runtime_1.jsx)(material_1.StepLabel, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h5", children: "Loading OpenAPI Document" }) }), (0, jsx_runtime_1.jsxs)(material_1.StepContent, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 100, color: "success" }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("br", {}), typeof props.swagger === "string" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { children: "Fetching OpenAPI Document from" }), (0, jsx_runtime_1.jsx)("p", { children: (0, jsx_runtime_1.jsx)("a", { href: props.swagger, target: "_blank", children: props.swagger }) })] })) : ("Delivering OpenAPI Document to the composer"), fetchError !== null ? ((0, jsx_runtime_1.jsxs)(material_1.Alert, { severity: "error", children: [(0, jsx_runtime_1.jsx)(material_1.AlertTitle, { children: "Fetch Error" }), fetchError] })) : null] })] }, 0), (0, jsx_runtime_1.jsxs)(material_1.Step, { children: [(0, jsx_runtime_1.jsx)(material_1.StepLabel, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h5", children: "Generating Software Development Kit" }) }), (0, jsx_runtime_1.jsxs)(material_1.StepContent, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 100, color: "success" }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("br", {}), "Generating SDK functions...", (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsxs)("ul", { children: [(0, jsx_runtime_1.jsxs)("li", { children: ["total operations: #", Object.values(operations)
                                                            .reduce((a, b) => a + b, 0)
                                                            .toLocaleString()] }), Object.entries(operations).map(([method, count]) => ((0, jsx_runtime_1.jsxs)("li", { children: [method, ": #", count.toLocaleString()] })))] }), composerError !== null ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsxs)(material_1.Alert, { severity: "error", children: [(0, jsx_runtime_1.jsx)(material_1.AlertTitle, { children: "Composition Error" }), (0, jsx_runtime_1.jsx)("pre", { children: JSON.stringify(composerError, null, 2) })] })] })) : null] })] }, 1), (0, jsx_runtime_1.jsxs)(material_1.Step, { children: [(0, jsx_runtime_1.jsx)(material_1.StepLabel, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h5", children: "Composing TypeScript Project" }) }), (0, jsx_runtime_1.jsx)(material_1.StepContent, {})] }, 2)] })] }) }));
}
const getDocument = (url) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const response = yield fetch(url);
        if (response.status !== 200)
            return yield response.text();
        else if (url.endsWith(".yaml")) {
            const text = yield response.text();
            return (0, js_yaml_1.load)(text);
        }
        return yield response.json();
    }
    catch (error) {
        if (error instanceof Error)
            return error.message;
        return "Unknown error";
    }
});
const aggregateOperation = (document) => {
    var _a, _b;
    const map = {};
    if (!(typeof document === "object" && document !== null))
        return map;
    for (const collection of Object.values((_a = document.paths) !== null && _a !== void 0 ? _a : {}))
        if (typeof collection === "object" && collection !== null)
            for (const [method] of Object.entries(collection))
                if (method === "head" ||
                    method === "get" ||
                    method === "post" ||
                    method === "patch" ||
                    method === "put" ||
                    method === "delete")
                    map[method] = ((_b = map[method]) !== null && _b !== void 0 ? _b : 0) + 1;
    return map;
};
//# sourceMappingURL=NestiaEditorIframe.js.map