"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const sanitizeInternalFields_1 = __importDefault(require("../../utilities/sanitizeInternalFields"));
const errors_1 = require("../../errors");
const executeAccess_1 = __importDefault(require("../../auth/executeAccess"));
const types_1 = require("../../auth/types");
const fileExists_1 = __importDefault(require("../../uploads/fileExists"));
const afterRead_1 = require("../../fields/hooks/afterRead");
async function deleteOperation(incomingArgs) {
    let args = incomingArgs;
    // /////////////////////////////////////
    // beforeOperation - Collection
    // /////////////////////////////////////
    await args.collection.config.hooks.beforeOperation.reduce(async (priorHook, hook) => {
        await priorHook;
        args = (await hook({
            args,
            operation: 'delete',
        })) || args;
    }, Promise.resolve());
    const { depth, collection: { Model, config: collectionConfig, }, id, req, req: { locale, payload: { config, preferences, }, }, overrideAccess, showHiddenFields, } = args;
    // /////////////////////////////////////
    // Access
    // /////////////////////////////////////
    const accessResults = !overrideAccess ? await (0, executeAccess_1.default)({ req, id }, collectionConfig.access.delete) : true;
    const hasWhereAccess = (0, types_1.hasWhereAccessResult)(accessResults);
    // /////////////////////////////////////
    // beforeDelete - Collection
    // /////////////////////////////////////
    await collectionConfig.hooks.beforeDelete.reduce(async (priorHook, hook) => {
        await priorHook;
        return hook({
            req,
            id,
        });
    }, Promise.resolve());
    // /////////////////////////////////////
    // Retrieve document
    // /////////////////////////////////////
    const queryToBuild = {
        where: {
            and: [
                {
                    id: {
                        equals: id,
                    },
                },
            ],
        },
    };
    if ((0, types_1.hasWhereAccessResult)(accessResults)) {
        queryToBuild.where.and.push(accessResults);
    }
    const query = await Model.buildQuery(queryToBuild, locale);
    const docToDelete = await Model.findOne(query);
    if (!docToDelete && !hasWhereAccess)
        throw new errors_1.NotFound();
    if (!docToDelete && hasWhereAccess)
        throw new errors_1.Forbidden();
    const resultToDelete = docToDelete.toJSON({ virtuals: true });
    // /////////////////////////////////////
    // Delete any associated files
    // /////////////////////////////////////
    if (collectionConfig.upload) {
        const { staticDir } = collectionConfig.upload;
        const staticPath = path_1.default.resolve(config.paths.configDir, staticDir);
        const fileToDelete = `${staticPath}/${resultToDelete.filename}`;
        if (await (0, fileExists_1.default)(fileToDelete)) {
            fs_1.default.unlink(fileToDelete, (err) => {
                if (err) {
                    throw new errors_1.ErrorDeletingFile();
                }
            });
        }
        if (resultToDelete.sizes) {
            Object.values(resultToDelete.sizes).forEach(async (size) => {
                const sizeToDelete = `${staticPath}/${size.filename}`;
                if (await (0, fileExists_1.default)(sizeToDelete)) {
                    fs_1.default.unlink(sizeToDelete, (err) => {
                        if (err) {
                            throw new errors_1.ErrorDeletingFile();
                        }
                    });
                }
            });
        }
    }
    // /////////////////////////////////////
    // Delete document
    // /////////////////////////////////////
    const doc = await Model.findOneAndDelete({ _id: id });
    let result = doc.toJSON({ virtuals: true });
    // custom id type reset
    result.id = result._id;
    result = JSON.stringify(result);
    result = JSON.parse(result);
    result = (0, sanitizeInternalFields_1.default)(result);
    // /////////////////////////////////////
    // Delete Preferences
    // /////////////////////////////////////
    if (collectionConfig.auth) {
        await preferences.Model.deleteMany({ user: id, userCollection: collectionConfig.slug });
    }
    await preferences.Model.deleteMany({ key: `collection-${collectionConfig.slug}-${id}` });
    // /////////////////////////////////////
    // afterDelete - Collection
    // /////////////////////////////////////
    await collectionConfig.hooks.afterDelete.reduce(async (priorHook, hook) => {
        await priorHook;
        result = await hook({ req, id, doc: result }) || result;
    }, Promise.resolve());
    // /////////////////////////////////////
    // afterRead - Fields
    // /////////////////////////////////////
    result = await (0, afterRead_1.afterRead)({
        depth,
        doc: result,
        entityConfig: collectionConfig,
        overrideAccess,
        req,
        showHiddenFields,
    });
    // /////////////////////////////////////
    // afterRead - Collection
    // /////////////////////////////////////
    await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
        await priorHook;
        result = await hook({
            req,
            doc: result,
        }) || result;
    }, Promise.resolve());
    // /////////////////////////////////////
    // 8. Return results
    // /////////////////////////////////////
    return result;
}
exports.default = deleteOperation;
//# sourceMappingURL=data:application/json;base64, 