"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.initState = exports.formatContent = exports.parseContent = exports.getMocks = void 0;
const lodash_1 = __importDefault(require("lodash"));
const formatter_1 = require("./formatter");
const merger_1 = require("./merger");
const mocker_1 = require("./mocker");
const parser_1 = require("./parser");
/**
 * get mocks
 * page & template mocks
 * @param data page content
 * @returns
 */
const getMocks = (data) => {
    var _a, _b;
    const mocks = data.mock ? [data.mock] : [];
    (_b = (_a = data.relations) === null || _a === void 0 ? void 0 : _a.templates) === null || _b === void 0 ? void 0 : _b.forEach((template) => {
        if (template.mock) {
            mocks.push(template.mock);
        }
    });
    return mocks;
};
exports.getMocks = getMocks;
/**
 * parse content
 * @param data page content
 * @param opt parse options
 * @returns
 */
const parseContent = (data, opt) => __awaiter(void 0, void 0, void 0, function* () {
    var _a;
    const { application, locale, extendContent, file } = opt || {};
    const { type } = file || {};
    let parsed = Object.assign({}, data);
    // merge
    if (extendContent) {
        parsed = (0, merger_1.merge)(parsed, extendContent);
        if (!parsed) {
            return null;
        }
    }
    const parsedSchemas = lodash_1.default.cloneDeep(parsed.content.schemas);
    backupParsedProps(parsedSchemas);
    parsed = Object.assign(Object.assign({}, parsed), { content: Object.assign(Object.assign({}, parsed.content), { schemas: parsedSchemas }) });
    // mock
    if (!!((_a = parsed.mock) === null || _a === void 0 ? void 0 : _a.enable) && opt.mocks.length > 0) {
        parsed = (0, mocker_1.mock)(parsed, {
            applicationId: application.id,
            extendContent,
            mocks: opt.mocks,
        });
        if (!parsed) {
            return null;
        }
    }
    // parse
    if (type === 'page') {
        parsed = yield (0, parser_1.parse)(parsed, {
            application,
            locale,
        });
    }
    return parsed;
});
exports.parseContent = parseContent;
/**
 * format content
 * @param parsed parsed content
 * @param opt options
 * @returns
 */
const formatContent = (parsed, opt) => {
    const result = (0, formatter_1.format)(parsed, Object.assign({}, opt));
    return result;
};
exports.formatContent = formatContent;
/**
 * init state
 * parse,mock,merge,formatted result
 * all events & changed will use it to get updated data
 * @param page
 * @param opt
 * @returns
 */
const initState = (page, opt) => __awaiter(void 0, void 0, void 0, function* () {
    console.time('INIT_STATE');
    // get mocks
    const mocks = (0, exports.getMocks)(page);
    // parse content
    const parsed = yield (0, exports.parseContent)(page, {
        application: opt.application,
        extendContent: lodash_1.default.cloneDeep(opt.extendPage),
        locale: opt.locale,
        mocks,
        file: opt.file,
    });
    if (!parsed) {
        return null;
    }
    // format content
    const formatted = (0, exports.formatContent)(parsed, {
        origin: page,
        extend: opt.extendPage,
        mocks,
        components: opt.components,
    });
    console.timeEnd('INIT_STATE');
    return formatted;
});
exports.initState = initState;
const backupParsedProps = (schemas = []) => {
    schemas.forEach((item) => {
        if (item.children) {
            backupParsedProps(item.children);
        }
        item.__parsedProps = Object.assign({}, item.props);
    });
};
