"use strict";
const config_1 = require("@n8n/config");
const db_1 = require("@n8n/db");
const di_1 = require("@n8n/di");
const typeorm_1 = require("@n8n/typeorm");
const zod_1 = require("zod");
const bad_request_error_1 = require("../../../../errors/response-errors/bad-request.error");
const not_found_error_1 = require("../../../../errors/response-errors/not-found.error");
const event_service_1 = require("../../../../events/event.service");
const workflow_finder_service_1 = require("../../../../workflows/workflow-finder.service");
const workflow_history_service_1 = require("../../../../workflows/workflow-history/workflow-history.service");
const workflow_service_1 = require("../../../../workflows/workflow.service");
const workflow_service_ee_1 = require("../../../../workflows/workflow.service.ee");
const workflows_service_1 = require("./workflows.service");
const global_middleware_1 = require("../../shared/middlewares/global.middleware");
const pagination_service_1 = require("../../shared/services/pagination.service");
module.exports = {
    createWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:create'),
        async (req, res) => {
            const createdWorkflow = await (0, workflows_service_1.createWorkflow)(req.user, req.body);
            return res.json(createdWorkflow);
        },
    ],
    transferWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:move'),
        (0, global_middleware_1.projectScope)('workflow:move', 'workflow'),
        async (req, res) => {
            const { id: workflowId } = req.params;
            const body = zod_1.z.object({ destinationProjectId: zod_1.z.string() }).parse(req.body);
            await di_1.Container.get(workflow_service_ee_1.EnterpriseWorkflowService).transferWorkflow(req.user, workflowId, body.destinationProjectId);
            res.status(204).send();
        },
    ],
    deleteWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:delete'),
        (0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
        async (req, res) => {
            const { id: workflowId } = req.params;
            const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).delete(req.user, workflowId, true);
            if (!workflow) {
                return res.status(404).json({ message: 'Not Found' });
            }
            return res.json(workflow);
        },
    ],
    getWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:read'),
        (0, global_middleware_1.projectScope)('workflow:read', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            const { excludePinnedData = false } = req.query;
            const workflow = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findWorkflowForUser(id, req.user, ['workflow:read'], {
                includeTags: !di_1.Container.get(config_1.GlobalConfig).tags.disabled,
                includeActiveVersion: true,
            });
            if (!workflow) {
                return res.status(404).json({ message: 'Not Found' });
            }
            if (excludePinnedData) {
                delete workflow.pinData;
            }
            di_1.Container.get(event_service_1.EventService).emit('user-retrieved-workflow', {
                userId: req.user.id,
                publicApi: true,
            });
            return res.json(workflow);
        },
    ],
    getWorkflowVersion: [
        (0, global_middleware_1.publicApiScope)('workflow:read'),
        (0, global_middleware_1.projectScope)('workflow:read', 'workflow'),
        async (req, res) => {
            const { id: workflowId, versionId } = req.params;
            try {
                const version = await di_1.Container.get(workflow_history_service_1.WorkflowHistoryService).getVersion(req.user, workflowId, versionId, { includePublishHistory: false });
                di_1.Container.get(event_service_1.EventService).emit('user-retrieved-workflow-version', {
                    userId: req.user.id,
                    publicApi: true,
                });
                const { autosaved, ...versionWithoutInternalFields } = version;
                return res.json(versionWithoutInternalFields);
            }
            catch (error) {
                return res.status(404).json({ message: 'Version not found' });
            }
        },
    ],
    getWorkflows: [
        (0, global_middleware_1.publicApiScope)('workflow:list'),
        global_middleware_1.validCursor,
        async (req, res) => {
            const { offset = 0, limit = 100, excludePinnedData = false, active, tags, name, projectId, } = req.query;
            const where = {
                ...(name !== undefined && { name: (0, typeorm_1.Like)('%' + name.trim() + '%') }),
            };
            if (active !== undefined) {
                if (active) {
                    where.activeVersionId = (0, typeorm_1.Not)((0, typeorm_1.IsNull)());
                }
                else {
                    where.activeVersionId = (0, typeorm_1.IsNull)();
                }
            }
            if (['global:owner', 'global:admin'].includes(req.user.role.slug)) {
                if (tags) {
                    const workflowIds = await di_1.Container.get(db_1.TagRepository).getWorkflowIdsViaTags((0, workflows_service_1.parseTagNames)(tags));
                    where.id = (0, typeorm_1.In)(workflowIds);
                }
                if (projectId) {
                    const workflowIds = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findAllWorkflowIdsForUser(req.user, ['workflow:read'], undefined, projectId);
                    if (workflowIds.length === 0) {
                        return res.status(200).json({
                            data: [],
                            nextCursor: null,
                        });
                    }
                    where.id = (0, typeorm_1.In)(workflowIds);
                }
            }
            else {
                const options = {};
                if (tags) {
                    options.workflowIds = await di_1.Container.get(db_1.TagRepository).getWorkflowIdsViaTags((0, workflows_service_1.parseTagNames)(tags));
                }
                let workflowIds = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findAllWorkflowIdsForUser(req.user, ['workflow:read'], undefined, projectId);
                if (options.workflowIds) {
                    workflowIds = options.workflowIds.filter((id) => workflowIds.includes(id));
                }
                if (!workflowIds.length) {
                    return res.status(200).json({
                        data: [],
                        nextCursor: null,
                    });
                }
                where.id = (0, typeorm_1.In)(workflowIds);
            }
            const selectFields = [
                'id',
                'name',
                'active',
                'activeVersionId',
                'createdAt',
                'updatedAt',
                'isArchived',
                'nodes',
                'connections',
                'settings',
                'staticData',
                'meta',
                'versionId',
                'triggerCount',
                'shared',
            ];
            if (!excludePinnedData) {
                selectFields.push('pinData');
            }
            const relations = ['shared', 'activeVersion'];
            if (!di_1.Container.get(config_1.GlobalConfig).tags.disabled) {
                relations.push('tags');
            }
            const [workflows, count] = await di_1.Container.get(db_1.WorkflowRepository).findAndCount({
                skip: offset,
                take: limit,
                select: selectFields,
                relations,
                where,
            });
            if (excludePinnedData) {
                workflows.forEach((workflow) => {
                    delete workflow.pinData;
                });
            }
            di_1.Container.get(event_service_1.EventService).emit('user-retrieved-all-workflows', {
                userId: req.user.id,
                publicApi: true,
            });
            return res.json({
                data: workflows,
                nextCursor: (0, pagination_service_1.encodeNextCursor)({
                    offset,
                    limit,
                    numberOfTotalRecords: count,
                }),
            });
        },
    ],
    updateWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:update'),
        (0, global_middleware_1.projectScope)('workflow:update', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            const updateData = new db_1.WorkflowEntity();
            Object.assign(updateData, req.body);
            try {
                const updatedWorkflow = await di_1.Container.get(workflow_service_1.WorkflowService).update(req.user, updateData, id, {
                    forceSave: true,
                    publicApi: true,
                    publishIfActive: true,
                });
                return res.json(updatedWorkflow);
            }
            catch (error) {
                if (error instanceof not_found_error_1.NotFoundError) {
                    return res.status(404).json({ message: 'Not Found' });
                }
                if (error instanceof Error) {
                    return res.status(400).json({ message: error.message });
                }
                throw error;
            }
        },
    ],
    activateWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:activate'),
        (0, global_middleware_1.projectScope)('workflow:publish', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            const { versionId, name, description } = req.body;
            try {
                const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).activateWorkflow(req.user, id, { versionId, name, description }, true);
                return res.json(workflow);
            }
            catch (error) {
                if (error instanceof not_found_error_1.NotFoundError) {
                    return res.status(404).json({ message: 'Not Found' });
                }
                if (error instanceof Error) {
                    return res.status(400).json({ message: error.message });
                }
                throw error;
            }
        },
    ],
    deactivateWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:deactivate'),
        (0, global_middleware_1.projectScope)('workflow:unpublish', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            try {
                const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).deactivateWorkflow(req.user, id, {
                    publicApi: true,
                });
                return res.json(workflow);
            }
            catch (error) {
                if (error instanceof not_found_error_1.NotFoundError) {
                    return res.status(404).json({ message: 'Not Found' });
                }
                if (error instanceof Error) {
                    return res.status(400).json({ message: error.message });
                }
                throw error;
            }
        },
    ],
    getWorkflowTags: [
        (0, global_middleware_1.publicApiScope)('workflowTags:list'),
        (0, global_middleware_1.projectScope)('workflow:read', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            if (di_1.Container.get(config_1.GlobalConfig).tags.disabled) {
                return res.status(400).json({ message: 'Workflow Tags Disabled' });
            }
            const workflow = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findWorkflowForUser(id, req.user, ['workflow:read']);
            if (!workflow) {
                return res.status(404).json({ message: 'Not Found' });
            }
            const tags = await (0, workflows_service_1.getWorkflowTags)(id);
            return res.json(tags);
        },
    ],
    updateWorkflowTags: [
        (0, global_middleware_1.publicApiScope)('workflowTags:update'),
        (0, global_middleware_1.projectScope)('workflow:update', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            const newTags = req.body.map((newTag) => newTag.id);
            if (di_1.Container.get(config_1.GlobalConfig).tags.disabled) {
                return res.status(400).json({ message: 'Workflow Tags Disabled' });
            }
            const sharedWorkflow = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findWorkflowForUser(id, req.user, ['workflow:update']);
            if (!sharedWorkflow) {
                return res.status(404).json({ message: 'Not Found' });
            }
            let tags;
            try {
                await (0, workflows_service_1.updateTags)(id, newTags);
                tags = await (0, workflows_service_1.getWorkflowTags)(id);
            }
            catch (error) {
                if (error instanceof typeorm_1.QueryFailedError) {
                    return res.status(404).json({ message: 'Some tags not found' });
                }
                else {
                    throw error;
                }
            }
            return res.json(tags);
        },
    ],
    archiveWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:delete'),
        (0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            try {
                const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).archiveForPublicApi(req.user, id);
                if (!workflow) {
                    throw new not_found_error_1.NotFoundError('Workflow not found');
                }
                return res.json(workflow);
            }
            catch (error) {
                if (error instanceof not_found_error_1.NotFoundError) {
                    return res.status(404).json({ message: 'Workflow Not Found' });
                }
                throw error;
            }
        },
    ],
    unarchiveWorkflow: [
        (0, global_middleware_1.publicApiScope)('workflow:delete'),
        (0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
        async (req, res) => {
            const { id } = req.params;
            try {
                const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).unarchiveForPublicApi(req.user, id);
                if (!workflow) {
                    throw new not_found_error_1.NotFoundError('Workflow not found');
                }
                return res.json(workflow);
            }
            catch (error) {
                if (error instanceof not_found_error_1.NotFoundError) {
                    return res.status(404).json({ message: 'Workflow Not Found' });
                }
                if (error instanceof bad_request_error_1.BadRequestError) {
                    return res.status(error.httpStatusCode).json({ message: error.message });
                }
                throw error;
            }
        },
    ],
};
//# sourceMappingURL=workflows.handler.js.map