"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "PrintQueueController", {
    enumerable: true,
    get: function() {
        return PrintQueueController;
    }
});
const _awilixexpress = require("awilix-express");
const _serverconstants = require("../server.constants");
const _express = require("express");
const _authenticate = require("../middleware/authenticate");
const _authorizationconstants = require("../constants/authorization.constants");
const _printqueueservice = require("../services/print-queue.service");
const _printjobservice = require("../services/orm/print-job.service");
const _filestorageservice = require("../services/file-storage.service");
const _printercache = require("../state/printer.cache");
const _loggerfactory = require("../handlers/logger-factory");
const _paramconvertermiddleware = require("../middleware/param-converter.middleware");
const _runtimeexceptions = require("../exceptions/runtime.exceptions");
function _ts_decorate(decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
class PrintQueueController {
    printQueueService;
    printJobService;
    fileStorageService;
    printerCache;
    logger;
    constructor(loggerFactory, printQueueService, printJobService, fileStorageService, printerCache){
        this.printQueueService = printQueueService;
        this.printJobService = printJobService;
        this.fileStorageService = fileStorageService;
        this.printerCache = printerCache;
        this.logger = loggerFactory(PrintQueueController.name);
    }
    async getGlobalQueue(req, res) {
        try {
            const page = Number.parseInt(req.query.page) || 1;
            const pageSize = Number.parseInt(req.query.pageSize) || 50;
            if (page < 1 || pageSize < 1 || pageSize > 200) {
                res.status(400).send({
                    error: "Invalid page or pageSize parameters"
                });
                return;
            }
            const [jobs, totalCount] = await this.printQueueService.getGlobalQueuePaged(page, pageSize);
            const queueItems = jobs.map((job)=>({
                    jobId: job.id,
                    fileName: job.fileName,
                    printerId: job.printerId,
                    printerName: job.printerName || job.printer?.name,
                    queuePosition: job.queuePosition,
                    status: job.status,
                    createdAt: job.createdAt,
                    estimatedTimeSeconds: job.metadata?.gcodePrintTimeSeconds,
                    filamentGrams: job.metadata?.filamentUsedGrams
                }));
            res.send({
                items: queueItems,
                page,
                pageSize,
                totalCount,
                totalPages: Math.ceil(totalCount / pageSize)
            });
        } catch (error) {
            this.logger.error(`Failed to get global queue: ${error}`);
            res.status(500).send({
                error: "Failed to get global queue"
            });
        }
    }
    async getQueue(req, res) {
        const printerId = req.local.printerId;
        try {
            const queue = await this.printQueueService.getQueue(printerId);
            res.send({
                printerId,
                queue,
                count: queue.length
            });
        } catch (error) {
            this.logger.error(`Failed to get queue for printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to get queue"
            });
        }
    }
    async addToQueue(req, res) {
        const printerId = req.local.printerId;
        const jobId = req.local.jobId;
        const position = req.body.position === undefined ? undefined : Number.parseInt(req.body.position);
        try {
            await this.printQueueService.addToQueue(printerId, jobId, position);
            const queue = await this.printQueueService.getQueue(printerId);
            res.send({
                message: "Job added to queue",
                printerId,
                jobId,
                position,
                queue
            });
        } catch (error) {
            this.logger.error(`Failed to add job ${jobId} to queue: ${error}`);
            res.status(500).send({
                error: "Failed to add to queue",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
    async reorderQueue(req, res) {
        const printerId = req.local.printerId;
        const jobIds = req.body.jobIds;
        if (!Array.isArray(jobIds)) {
            res.status(400).send({
                error: "jobIds must be an array"
            });
            return;
        }
        try {
            await this.printQueueService.reorderQueue(printerId, jobIds);
            const queue = await this.printQueueService.getQueue(printerId);
            res.send({
                message: "Queue reordered",
                printerId,
                queue
            });
        } catch (error) {
            this.logger.error(`Failed to reorder queue for printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to reorder queue",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
    async clearQueue(req, res) {
        const printerId = req.local.printerId;
        try {
            await this.printQueueService.clearQueue(printerId);
            res.send({
                message: "Queue cleared",
                printerId
            });
        } catch (error) {
            this.logger.error(`Failed to clear queue for printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to clear queue",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
    async removeFromQueue(req, res) {
        const printerId = req.local.printerId;
        const jobId = req.local.jobId;
        try {
            await this.printQueueService.removeFromQueue(jobId);
            const queue = await this.printQueueService.getQueue(printerId);
            res.send({
                message: "Job removed from queue",
                printerId,
                jobId,
                queue
            });
        } catch (error) {
            this.logger.error(`Failed to remove job ${jobId} from queue: ${error}`);
            res.status(500).send({
                error: "Failed to remove from queue",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
    async getNextInQueue(req, res) {
        const printerId = req.local.printerId;
        try {
            const nextJob = await this.printQueueService.getNextInQueue(printerId);
            res.send({
                printerId,
                nextJob
            });
        } catch (error) {
            this.logger.error(`Failed to get next job for printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to get next job"
            });
        }
    }
    async processQueue(req, res) {
        const printerId = req.local.printerId;
        try {
            const nextJob = await this.printQueueService.processQueue(printerId);
            if (!nextJob) {
                res.send({
                    message: "Queue is empty",
                    printerId,
                    nextJob: null
                });
                return;
            }
            res.send({
                message: "Processing next job in queue",
                printerId,
                nextJob
            });
        } catch (error) {
            this.logger.error(`Failed to process queue for printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to process queue",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
    async createJobFromFile(req, res) {
        const printerId = req.local.printerId;
        const { fileStorageId, addToQueue = true, position } = req.body;
        if (!fileStorageId) {
            res.status(400).send({
                error: "fileStorageId is required"
            });
            return;
        }
        try {
            const fileExists = await this.fileStorageService.fileExists(fileStorageId);
            if (!fileExists) {
                throw new _runtimeexceptions.NotFoundException("File not found in storage");
            }
            const metadata = await this.fileStorageService.loadMetadata(fileStorageId);
            if (!metadata) {
                res.status(400).send({
                    error: "File has no metadata. Please analyze the file first."
                });
                return;
            }
            const printer = await this.printerCache.getCachedPrinterOrThrowAsync(printerId);
            const job = await this.printJobService.createPendingJob(printerId, metadata._originalFileName || metadata.fileName || "Unknown", metadata, printer.name);
            job.fileStorageId = fileStorageId;
            job.fileHash = metadata._fileHash;
            job.analysisState = "ANALYZED";
            job.analyzedAt = new Date();
            if (metadata.fileFormat) {
                job.fileFormat = metadata.fileFormat;
            }
            await this.printJobService.updateJob(job);
            if (addToQueue) {
                await this.printQueueService.addToQueue(printerId, job.id, position);
            }
            this.logger.log(`Created job ${job.id} from file storage ${fileStorageId} for printer ${printerId}${addToQueue ? " and added to queue" : ""}`);
            res.send({
                id: job.id,
                printerId: job.printerId,
                printerName: job.printerName,
                fileName: job.fileName,
                fileStorageId: job.fileStorageId,
                status: job.status,
                analysisState: job.analysisState,
                createdAt: job.createdAt,
                addedToQueue: addToQueue
            });
        } catch (error) {
            this.logger.error(`Failed to create job from file ${fileStorageId}: ${error}`);
            res.status(500).send({
                error: "Failed to create job from file"
            });
        }
    }
    async submitToPrinter(req, res) {
        const printerId = req.local.printerId;
        const jobId = req.local.jobId;
        try {
            await this.printQueueService.submitToPrinter(printerId, jobId);
            res.send({
                message: "Job submitted to printer for printing",
                printerId,
                jobId
            });
        } catch (error) {
            this.logger.error(`Failed to submit job ${jobId} to printer ${printerId}: ${error}`);
            res.status(500).send({
                error: "Failed to submit job to printer",
                message: error instanceof Error ? error.message : "Unknown error"
            });
        }
    }
}
_ts_decorate([
    (0, _awilixexpress.GET)(),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "getGlobalQueue", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:printerId"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "getQueue", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:printerId/add/:jobId"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId"),
        (0, _paramconvertermiddleware.ParamId)("jobId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "addToQueue", null);
_ts_decorate([
    (0, _awilixexpress.PUT)(),
    (0, _awilixexpress.route)("/:printerId/reorder"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "reorderQueue", null);
_ts_decorate([
    (0, _awilixexpress.DELETE)(),
    (0, _awilixexpress.route)("/:printerId/clear"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "clearQueue", null);
_ts_decorate([
    (0, _awilixexpress.DELETE)(),
    (0, _awilixexpress.route)("/:printerId/:jobId"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId"),
        (0, _paramconvertermiddleware.ParamId)("jobId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "removeFromQueue", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:printerId/next"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "getNextInQueue", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:printerId/process"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "processQueue", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:printerId/from-file"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "createJobFromFile", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:printerId/submit/:jobId"),
    (0, _awilixexpress.before)([
        (0, _paramconvertermiddleware.ParamId)("printerId"),
        (0, _paramconvertermiddleware.ParamId)("jobId")
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _express.Request === "undefined" ? Object : _express.Request,
        typeof _express.Response === "undefined" ? Object : _express.Response
    ]),
    _ts_metadata("design:returntype", Promise)
], PrintQueueController.prototype, "submitToPrinter", null);
PrintQueueController = _ts_decorate([
    (0, _awilixexpress.route)(_serverconstants.AppConstants.apiRoute + "/print-queue"),
    (0, _awilixexpress.before)([
        (0, _authenticate.authenticate)(),
        (0, _authenticate.authorizeRoles)([
            _authorizationconstants.ROLES.ADMIN,
            _authorizationconstants.ROLES.OPERATOR
        ])
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _loggerfactory.ILoggerFactory === "undefined" ? Object : _loggerfactory.ILoggerFactory,
        typeof _printqueueservice.PrintQueueService === "undefined" ? Object : _printqueueservice.PrintQueueService,
        typeof _printjobservice.PrintJobService === "undefined" ? Object : _printjobservice.PrintJobService,
        typeof _filestorageservice.FileStorageService === "undefined" ? Object : _filestorageservice.FileStorageService,
        typeof _printercache.PrinterCache === "undefined" ? Object : _printercache.PrinterCache
    ])
], PrintQueueController);

//# sourceMappingURL=print-queue.controller.js.map