"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "PrinterController", {
    enumerable: true,
    get: function() {
        return PrinterController;
    }
});
const _awilixexpress = require("awilix-express");
const _authenticate = require("../middleware/authenticate");
const _validators = require("../handlers/validators");
const _printercontrollervalidation = require("./validation/printer-controller.validation");
const _serverconstants = require("../server.constants");
const _printer = require("../middleware/printer");
const _correlationtokenutil = require("../utils/correlation-token.util");
const _authorizationconstants = require("../constants/authorization.constants");
const _printersocketstore = require("../state/printer-socket.store");
const _testprintersocketstore = require("../state/test-printer-socket.store");
const _printercache = require("../state/printer.cache");
const _printereventscache = require("../state/printer-events.cache");
const _floorstore = require("../state/floor.store");
const _loggerfactory = require("../handlers/logger-factory");
const _express = require("express");
const _printerserviceinterface = require("../services/interfaces/printer.service.interface");
const _axios = require("axios");
const _faileddependencyexception = require("../exceptions/failed-dependency.exception");
const _runtimeexceptions = require("../exceptions/runtime.exceptions");
const _printerapiinterface = require("../services/printer-api.interface");
const _printerapifactory = require("../services/printer-api.factory");
const _normalizeurl = require("../utils/normalize-url");
const _urlutils = require("../utils/url.utils");
const _printerresolver = require("../middleware/printer-resolver");
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 PrinterController {
    printerApiFactory;
    printerSocketStore;
    testPrinterSocketStore;
    printerService;
    printerCache;
    printerEventsCache;
    printerApi;
    floorStore;
    logger;
    constructor(loggerFactory, printerApiFactory, printerSocketStore, testPrinterSocketStore, printerService, printerCache, printerEventsCache, printerApi, floorStore){
        this.printerApiFactory = printerApiFactory;
        this.printerSocketStore = printerSocketStore;
        this.testPrinterSocketStore = testPrinterSocketStore;
        this.printerService = printerService;
        this.printerCache = printerCache;
        this.printerEventsCache = printerEventsCache;
        this.printerApi = printerApi;
        this.floorStore = floorStore;
        this.logger = loggerFactory(PrinterController.name);
    }
    async list(req, res) {
        res.send(await this.printerCache.listCachedPrinters(true));
    }
    async create(req, res) {
        const newPrinter = req.body;
        if (req.query.forceSave !== "true") {
            await this.testPrintApiConnection(newPrinter);
        }
        const createdPrinter = await this.printerService.create(newPrinter);
        res.send(await this.printerCache.getCachedPrinterOrThrowAsync(createdPrinter.id));
    }
    async createBatch(req, res) {
        const importResult = await this.printerService.batchImport(req.body);
        res.send(importResult);
    }
    async getPrinter(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        res.send(await this.printerCache.getCachedPrinterOrThrowAsync(currentPrinterId));
    }
    async getPrinterSocketInfo(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        res.send(await this.printerEventsCache.getPrinterSocketEvents(currentPrinterId));
    }
    async update(req, res) {
        const forceSave = req.query.forceSave === "true";
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        const updatedPrinter = req.body;
        if (!forceSave) {
            await this.testPrintApiConnection(updatedPrinter);
        }
        await this.printerService.update(currentPrinterId, updatedPrinter);
        res.send(await this.printerCache.getCachedPrinterOrThrowAsync(currentPrinterId));
    }
    async delete(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        await this.printerService.delete(currentPrinterId);
        await this.floorStore.removePrinterFromAnyFloor(currentPrinterId);
        res.send();
    }
    async updateEnabled(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        const data = await (0, _validators.validateMiddleware)(req, _printercontrollervalidation.updatePrinterEnabledSchema);
        await this.printerService.updateEnabled(currentPrinterId, data.enabled);
        res.send({});
    }
    async updatePrinterDisabledReason(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        const data = await (0, _validators.validateMiddleware)(req, _printercontrollervalidation.updatePrinterDisabledReasonSchema);
        await this.printerService.updateDisabledReason(currentPrinterId, data.disabledReason);
        res.send({});
    }
    async refreshPrinterSocket(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        this.printerSocketStore.reconnectPrinterAdapter(currentPrinterId);
        await this.printerEventsCache.deletePrinterSocketEvents(currentPrinterId);
        res.send({});
    }
    async testConnection(req, res) {
        if (req.body.printerURL?.length) {
            req.body.printerURL = (0, _normalizeurl.normalizeUrl)(req.body.printerURL, {
                defaultProtocol: _urlutils.defaultHttpProtocol
            });
        }
        const newPrinter = await (0, _validators.validateMiddleware)(req, _printercontrollervalidation.testPrinterApiSchema);
        const printerCorrelationToken = (0, _correlationtokenutil.generateCorrelationToken)();
        this.logger.log(`Testing printer with correlation token ${printerCorrelationToken}`);
        try {
            await this.testPrinterSocketStore.setupTestPrinter(printerCorrelationToken, newPrinter);
        } catch (e) {
            res.send({
                correlationToken: printerCorrelationToken,
                failure: true,
                error: e.toString()
            });
            return;
        }
        res.send({
            correlationToken: printerCorrelationToken
        });
    }
    async getPrinterLoginDetails(req, res) {
        const { printerLogin } = (0, _printerresolver.getScopedPrinter)(req);
        res.send(printerLogin);
    }
    async sendEmergencyM112(req, res) {
        const { printerApi } = (0, _printerresolver.getScopedPrinter)(req);
        await printerApi.quickStop();
        res.send();
    }
    async sendSerialConnectCommand(req, res) {
        await this.printerApi.connect();
        res.send({});
    }
    async sendSerialDisconnectCommand(req, res) {
        await this.printerApi.disconnect();
        res.send({});
    }
    async movePrintHead(req, res) {
        await this.printerApi.movePrintHead(req.body);
        res.send({});
    }
    async homeAxes(req, res) {
        await this.printerApi.homeAxes(req.body);
        res.send({});
    }
    async pausePrint(req, res) {
        await this.printerApi.pausePrint();
        res.send({});
    }
    async resumePrint(req, res) {
        await this.printerApi.resumePrint();
        res.send({});
    }
    async cancelPrint(req, res) {
        await this.printerApi.cancelPrint();
        res.send({});
    }
    async restartServer(req, res) {
        await this.printerApi.restartServer();
        res.send();
    }
    async setFeedRate(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        const data = await (0, _validators.validateMiddleware)(req, _printercontrollervalidation.feedRateSchema);
        await this.printerService.updateFeedRate(currentPrinterId, data.feedRate);
        res.send({});
    }
    async setFlowRate(req, res) {
        const { currentPrinterId } = (0, _printerresolver.getScopedPrinter)(req);
        const data = await (0, _validators.validateMiddleware)(req, _printercontrollervalidation.flowRateSchema);
        await this.printerService.updateFlowRate(currentPrinterId, data.flowRate);
        res.send({});
    }
    async testPrintApiConnection(inputLoginDto) {
        await (0, _validators.validateInput)(inputLoginDto, _printercontrollervalidation.testPrinterApiSchema);
        this.logger.debug(`Testing API connection for printer type: ${inputLoginDto.printerType}`, inputLoginDto);
        try {
            const printerApi = this.printerApiFactory.getScopedPrinter(inputLoginDto);
            await printerApi.validateConnection();
            this.logger.debug("Connection validation completed successfully");
        } catch (e) {
            this.logger.log("Printer connection validation failed");
            this.logger.debug(`Error details: ${e}`);
            if (e instanceof _axios.AxiosError) {
                this.logger.debug(e.message + " " + e.status + " " + e.response?.status);
                switch(e.response?.status){
                    case 404:
                        break;
                    case 401:
                    case 403:
                        {
                            throw new _faileddependencyexception.FailedDependencyException("Authentication failed", e.response?.status);
                        }
                    case 0:
                    case 502:
                    case 503:
                        {
                            throw new _faileddependencyexception.FailedDependencyException("Printer service unreachable", e.response?.status);
                        }
                    default:
                        {
                            if (e.response?.status) {
                                throw new _faileddependencyexception.FailedDependencyException(`Reaching Printer service failed with status (code ${e.code})`, e.response?.status);
                            } else {
                                throw new _faileddependencyexception.FailedDependencyException(`Reaching Printer service failed without status (code ${e.code})`);
                            }
                        }
                }
            }
            throw new _runtimeexceptions.InternalServerException(`Could not call Printer service, internal problem`, e.stack);
        }
    }
}
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/"),
    _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)
], PrinterController.prototype, "list", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/"),
    _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)
], PrinterController.prototype, "create", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/batch"),
    _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)
], PrinterController.prototype, "createBatch", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:id"),
    _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)
], PrinterController.prototype, "getPrinter", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:id/socket"),
    _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)
], PrinterController.prototype, "getPrinterSocketInfo", null);
_ts_decorate([
    (0, _awilixexpress.PATCH)(),
    (0, _awilixexpress.route)("/:id"),
    _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)
], PrinterController.prototype, "update", null);
_ts_decorate([
    (0, _awilixexpress.DELETE)(),
    (0, _awilixexpress.route)("/:id"),
    _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)
], PrinterController.prototype, "delete", null);
_ts_decorate([
    (0, _awilixexpress.PATCH)(),
    (0, _awilixexpress.route)("/:id/enabled"),
    _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)
], PrinterController.prototype, "updateEnabled", null);
_ts_decorate([
    (0, _awilixexpress.PATCH)(),
    (0, _awilixexpress.route)("/:id/disabled-reason"),
    _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)
], PrinterController.prototype, "updatePrinterDisabledReason", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/refresh-socket"),
    _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)
], PrinterController.prototype, "refreshPrinterSocket", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/test-connection"),
    _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)
], PrinterController.prototype, "testConnection", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:id/login-details"),
    _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)
], PrinterController.prototype, "getPrinterLoginDetails", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/send-emergency-m112"),
    _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)
], PrinterController.prototype, "sendEmergencyM112", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/serial-connect"),
    _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)
], PrinterController.prototype, "sendSerialConnectCommand", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/serial-disconnect"),
    _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)
], PrinterController.prototype, "sendSerialDisconnectCommand", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/jog"),
    (0, _awilixexpress.route)("/:id/move"),
    _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)
], PrinterController.prototype, "movePrintHead", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/home"),
    _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)
], PrinterController.prototype, "homeAxes", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/job/pause"),
    _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)
], PrinterController.prototype, "pausePrint", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/job/resume"),
    _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)
], PrinterController.prototype, "resumePrint", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/job/stop"),
    (0, _awilixexpress.route)("/:id/job/cancel"),
    _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)
], PrinterController.prototype, "cancelPrint", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:id/octoprint/server/restart"),
    (0, _awilixexpress.route)("/:id/server/restart"),
    _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)
], PrinterController.prototype, "restartServer", null);
_ts_decorate([
    (0, _awilixexpress.PATCH)(),
    (0, _awilixexpress.route)("/:id/feed-rate"),
    _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)
], PrinterController.prototype, "setFeedRate", null);
_ts_decorate([
    (0, _awilixexpress.PATCH)(),
    (0, _awilixexpress.route)("/:id/flow-rate"),
    _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)
], PrinterController.prototype, "setFlowRate", null);
PrinterController = _ts_decorate([
    (0, _awilixexpress.route)(_serverconstants.AppConstants.apiRoute + "/printer"),
    (0, _awilixexpress.before)([
        (0, _authenticate.authenticate)(),
        (0, _authenticate.authorizeRoles)([
            _authorizationconstants.ROLES.OPERATOR,
            _authorizationconstants.ROLES.ADMIN
        ]),
        (0, _printer.printerResolveMiddleware)()
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _loggerfactory.ILoggerFactory === "undefined" ? Object : _loggerfactory.ILoggerFactory,
        typeof _printerapifactory.PrinterApiFactory === "undefined" ? Object : _printerapifactory.PrinterApiFactory,
        typeof _printersocketstore.PrinterSocketStore === "undefined" ? Object : _printersocketstore.PrinterSocketStore,
        typeof _testprintersocketstore.TestPrinterSocketStore === "undefined" ? Object : _testprintersocketstore.TestPrinterSocketStore,
        typeof _printerserviceinterface.IPrinterService === "undefined" ? Object : _printerserviceinterface.IPrinterService,
        typeof _printercache.PrinterCache === "undefined" ? Object : _printercache.PrinterCache,
        typeof _printereventscache.PrinterEventsCache === "undefined" ? Object : _printereventscache.PrinterEventsCache,
        typeof _printerapiinterface.IPrinterApi === "undefined" ? Object : _printerapiinterface.IPrinterApi,
        typeof _floorstore.FloorStore === "undefined" ? Object : _floorstore.FloorStore
    ])
], PrinterController);

//# sourceMappingURL=printer.controller.js.map