"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "SlicerCompatController", {
    enumerable: true,
    get: function() {
        return SlicerCompatController;
    }
});
const _awilixexpress = require("awilix-express");
const _express = require("express");
const _filestorageservice = require("../services/file-storage.service");
const _fileanalysisservice = require("../services/file-analysis.service");
const _multerservice = require("../services/core/multer.service");
const _loggerfactory = require("../handlers/logger-factory");
const _serverconstants = require("../server.constants");
const _slicerapikeymiddleware = require("../middleware/slicer-api-key.middleware");
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 SlicerCompatController {
    fileStorageService;
    fileAnalysisService;
    multerService;
    logger;
    constructor(loggerFactory, fileStorageService, fileAnalysisService, multerService){
        this.fileStorageService = fileStorageService;
        this.fileAnalysisService = fileAnalysisService;
        this.multerService = multerService;
        this.logger = loggerFactory(SlicerCompatController.name);
    }
    async getVersion(req, res) {
        res.send({
            api: "0.1",
            server: "1.9.0",
            text: "OctoPrint 1.9.3"
        });
    }
    async uploadFile(req, res) {
        let files;
        try {
            const acceptedExtensions = [
                ..._serverconstants.AppConstants.defaultAcceptedGcodeExtensions,
                ..._serverconstants.AppConstants.defaultAcceptedBambuExtensions
            ];
            files = await this.multerService.multerLoadFileAsync(req, res, acceptedExtensions, true);
            if (!files?.length) {
                res.status(400).send({
                    error: "No file uploaded"
                });
                return;
            }
            const file = files[0];
            const print = req.body.print === "true" || req.body.print === true;
            const select = req.body.select === "true" || req.body.select === true;
            this.logger.log(`OctoPrint-compatible upload: ${file.originalname} (print=${print}, select=${select})`);
            const fileHash = await this.fileStorageService.calculateFileHash(file.path);
            const fileStorageId = await this.fileStorageService.saveFile(file, fileHash);
            const filePath = this.fileStorageService.getFilePath(fileStorageId);
            let metadata = {};
            let thumbnails = [];
            try {
                const analysisResult = await this.fileAnalysisService.analyzeFile(filePath);
                metadata = analysisResult.metadata;
                thumbnails = analysisResult.thumbnails || [];
                if (thumbnails.length > 0) {
                    const thumbnailMetadata = await this.fileStorageService.saveThumbnails(fileStorageId, thumbnails);
                    this.logger.log(`Saved ${thumbnailMetadata.length} thumbnail(s) for ${fileStorageId}`);
                    await this.fileStorageService.saveMetadata(fileStorageId, metadata, fileHash, file.originalname, thumbnailMetadata);
                } else {
                    await this.fileStorageService.saveMetadata(fileStorageId, metadata, fileHash, file.originalname);
                }
            } catch (analysisError) {
                this.logger.error(`Failed to analyze uploaded file: ${analysisError}`);
            }
            try {
                this.multerService.clearUploadedFile(file);
            } catch (e) {
                this.logger.error(`Could not remove uploaded file from temporary storage`);
            }
            res.status(201).send({
                files: {
                    local: {
                        name: file.originalname,
                        origin: "local",
                        refs: {
                            resource: `/api/files/local/${fileStorageId}`,
                            download: `/api/files/local/${fileStorageId}`
                        }
                    }
                },
                done: true,
                _fdmMonster: {
                    fileStorageId,
                    fileHash,
                    analyzed: Object.keys(metadata).length > 0,
                    thumbnailCount: thumbnails.length,
                    printTime: metadata.gcodePrintTimeSeconds,
                    filament: metadata.filamentUsedGrams
                }
            });
            this.logger.log(`File uploaded to printer: ${file.originalname} -> ${fileStorageId}`);
        } catch (error) {
            if (files?.[0]?.path) {
                try {
                    this.multerService.clearUploadedFile(files[0]);
                } catch (e) {
                    this.logger.error(`Could not remove uploaded file from temporary storage`);
                }
            }
            throw error;
        }
    }
    async listFiles(req, res) {
        try {
            const files = await this.fileStorageService.listAllFiles();
            const knownFiles = files.map((file)=>({
                    name: file.metadata?._originalFileName || file.fileName,
                    path: file.fileStorageId,
                    type: "machinecode",
                    typePath: [
                        "machinecode",
                        file.fileFormat
                    ],
                    origin: "local",
                    refs: {
                        resource: `/api/files/local/${file.fileStorageId}`,
                        download: `/api/files/local/${file.fileStorageId}`
                    },
                    gcodeAnalysis: file.metadata ? {
                        estimatedPrintTime: file.metadata.gcodePrintTimeSeconds,
                        filament: {
                            tool0: {
                                length: file.metadata.filamentUsedMm,
                                volume: file.metadata.filamentUsedCm3
                            }
                        }
                    } : undefined,
                    date: Math.floor(file.createdAt.getTime() / 1000),
                    size: file.fileSize
                }));
            res.send({
                files: knownFiles,
                free: 0,
                total: 0
            });
        } catch (error) {
            this.logger.error(`Failed to list files via printer API: ${error}`);
            throw error;
        }
    }
    async getServer(req, res) {
        res.send({
            version: "1.9.0",
            safemode: null
        });
    }
}
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/version"),
    _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)
], SlicerCompatController.prototype, "getVersion", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/files/local"),
    _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)
], SlicerCompatController.prototype, "uploadFile", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/files"),
    _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)
], SlicerCompatController.prototype, "listFiles", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/server"),
    _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)
], SlicerCompatController.prototype, "getServer", null);
SlicerCompatController = _ts_decorate([
    (0, _awilixexpress.route)("/api"),
    (0, _awilixexpress.before)([
        (0, _slicerapikeymiddleware.slicerApiKeyAuth)()
    ]),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", [
        typeof _loggerfactory.ILoggerFactory === "undefined" ? Object : _loggerfactory.ILoggerFactory,
        typeof _filestorageservice.FileStorageService === "undefined" ? Object : _filestorageservice.FileStorageService,
        typeof _fileanalysisservice.FileAnalysisService === "undefined" ? Object : _fileanalysisservice.FileAnalysisService,
        typeof _multerservice.MulterService === "undefined" ? Object : _multerservice.MulterService
    ])
], SlicerCompatController);

//# sourceMappingURL=slicer-compat.controller.js.map