"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const executeAccess_1 = __importDefault(require("../../auth/executeAccess"));
const sanitizeInternalFields_1 = __importDefault(require("../../utilities/sanitizeInternalFields"));
const saveGlobalVersion_1 = require("../../versions/saveGlobalVersion");
const saveGlobalDraft_1 = require("../../versions/drafts/saveGlobalDraft");
const ensurePublishedGlobalVersion_1 = require("../../versions/ensurePublishedGlobalVersion");
const cleanUpFailedVersion_1 = __importDefault(require("../../versions/cleanUpFailedVersion"));
const auth_1 = require("../../auth");
const beforeChange_1 = require("../../fields/hooks/beforeChange");
const beforeValidate_1 = require("../../fields/hooks/beforeValidate");
const afterChange_1 = require("../../fields/hooks/afterChange");
const afterRead_1 = require("../../fields/hooks/afterRead");
async function update(args) {
    var _a;
    const { globalConfig, slug, req, req: { locale, payload, payload: { globals: { Model, }, }, }, depth, overrideAccess, showHiddenFields, draft: draftArg, autosave, } = args;
    let { data } = args;
    const shouldSaveDraft = Boolean(draftArg && ((_a = globalConfig.versions) === null || _a === void 0 ? void 0 : _a.drafts));
    // /////////////////////////////////////
    // 1. Retrieve and execute access
    // /////////////////////////////////////
    const accessResults = !overrideAccess ? await (0, executeAccess_1.default)({ req, data }, globalConfig.access.update) : true;
    // /////////////////////////////////////
    // Retrieve document
    // /////////////////////////////////////
    const queryToBuild = {
        where: {
            and: [
                {
                    globalType: {
                        equals: slug,
                    },
                },
            ],
        },
    };
    if ((0, auth_1.hasWhereAccessResult)(accessResults)) {
        queryToBuild.where.and.push(accessResults);
    }
    const query = await Model.buildQuery(queryToBuild, locale);
    // /////////////////////////////////////
    // 2. Retrieve document
    // /////////////////////////////////////
    let global = await Model.findOne(query);
    let globalJSON = {};
    if (global) {
        globalJSON = global.toJSON({ virtuals: true });
        const globalJSONString = JSON.stringify(globalJSON);
        globalJSON = JSON.parse(globalJSONString);
        if (globalJSON._id) {
            delete globalJSON._id;
        }
    }
    const originalDoc = await (0, afterRead_1.afterRead)({
        depth,
        doc: globalJSON,
        entityConfig: globalConfig,
        req,
        overrideAccess: true,
        showHiddenFields,
    });
    // /////////////////////////////////////
    // beforeValidate - Fields
    // /////////////////////////////////////
    data = await (0, beforeValidate_1.beforeValidate)({
        data,
        doc: originalDoc,
        entityConfig: globalConfig,
        operation: 'update',
        overrideAccess,
        req,
    });
    // /////////////////////////////////////
    // beforeValidate - Global
    // /////////////////////////////////////
    await globalConfig.hooks.beforeValidate.reduce(async (priorHook, hook) => {
        await priorHook;
        data = (await hook({
            data,
            req,
            originalDoc,
        })) || data;
    }, Promise.resolve());
    // /////////////////////////////////////
    // beforeChange - Global
    // /////////////////////////////////////
    await globalConfig.hooks.beforeChange.reduce(async (priorHook, hook) => {
        await priorHook;
        data = (await hook({
            data,
            req,
            originalDoc,
        })) || data;
    }, Promise.resolve());
    // /////////////////////////////////////
    // beforeChange - Fields
    // /////////////////////////////////////
    const result = await (0, beforeChange_1.beforeChange)({
        data,
        doc: originalDoc,
        docWithLocales: globalJSON,
        entityConfig: globalConfig,
        operation: 'update',
        req,
        skipValidation: shouldSaveDraft,
    });
    // /////////////////////////////////////
    // Create version from existing doc
    // /////////////////////////////////////
    let createdVersion;
    if (globalConfig.versions && !shouldSaveDraft) {
        createdVersion = await (0, saveGlobalVersion_1.saveGlobalVersion)({
            payload,
            config: globalConfig,
            req,
            docWithLocales: result,
        });
    }
    // /////////////////////////////////////
    // Update
    // /////////////////////////////////////
    if (shouldSaveDraft) {
        await (0, ensurePublishedGlobalVersion_1.ensurePublishedGlobalVersion)({
            payload,
            config: globalConfig,
            req,
            docWithLocales: result,
        });
        global = await (0, saveGlobalDraft_1.saveGlobalDraft)({
            payload,
            config: globalConfig,
            data: result,
            autosave,
        });
    }
    else {
        try {
            if (global) {
                global = await Model.findOneAndUpdate({ globalType: slug }, result, { new: true });
            }
            else {
                result.globalType = slug;
                global = await Model.create(result);
            }
        }
        catch (error) {
            (0, cleanUpFailedVersion_1.default)({
                payload,
                entityConfig: globalConfig,
                version: createdVersion,
            });
        }
    }
    global = JSON.stringify(global);
    global = JSON.parse(global);
    global = (0, sanitizeInternalFields_1.default)(global);
    // /////////////////////////////////////
    // afterRead - Fields
    // /////////////////////////////////////
    global = await (0, afterRead_1.afterRead)({
        depth,
        doc: global,
        entityConfig: globalConfig,
        req,
        overrideAccess,
        showHiddenFields,
    });
    // /////////////////////////////////////
    // afterRead - Global
    // /////////////////////////////////////
    await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
        await priorHook;
        global = await hook({
            doc: global,
            req,
        }) || global;
    }, Promise.resolve());
    // /////////////////////////////////////
    // afterChange - Fields
    // /////////////////////////////////////
    global = await (0, afterChange_1.afterChange)({
        data,
        doc: global,
        previousDoc: originalDoc,
        entityConfig: globalConfig,
        operation: 'update',
        req,
    });
    // /////////////////////////////////////
    // afterChange - Global
    // /////////////////////////////////////
    await globalConfig.hooks.afterChange.reduce(async (priorHook, hook) => {
        await priorHook;
        global = await hook({
            doc: global,
            previousDoc: originalDoc,
            req,
        }) || result;
    }, Promise.resolve());
    // /////////////////////////////////////
    // Return results
    // /////////////////////////////////////
    return global;
}
exports.default = update;
//# sourceMappingURL=data:application/json;base64, 