"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "FileStorageController", {
    enumerable: true,
    get: function() {
        return FileStorageController;
    }
});
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 _filestorageservice = require("../services/file-storage.service");
const _multerservice = require("../services/core/multer.service");
const _loggerfactory = require("../handlers/logger-factory");
const _fileanalysisservice = require("../services/file-analysis.service");
const _nodefs = require("node:fs");
const _nodepath = require("node:path");
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 FileStorageController {
    fileStorageService;
    multerService;
    fileAnalysisService;
    logger;
    constructor(loggerFactory, fileStorageService, multerService, fileAnalysisService){
        this.fileStorageService = fileStorageService;
        this.multerService = multerService;
        this.fileAnalysisService = fileAnalysisService;
        this.logger = loggerFactory(FileStorageController.name);
    }
    async listFiles(req, res) {
        try {
            const files = await this.fileStorageService.listAllFiles();
            res.send({
                files: files.map((file)=>({
                        fileStorageId: file.fileStorageId,
                        fileName: file.fileName,
                        fileFormat: file.fileFormat,
                        fileSize: file.fileSize,
                        fileHash: file.fileHash,
                        createdAt: file.createdAt,
                        thumbnailCount: file.thumbnailCount,
                        thumbnailsUrl: file.thumbnailCount > 0 ? `/api/file-storage/${file.fileStorageId}/thumbnail/0` : null,
                        metadata: file.metadata
                    })),
                totalCount: files.length
            });
        } catch (error) {
            this.logger.error(`Failed to list files: ${error}`);
            res.status(500).send({
                error: "Failed to list files"
            });
        }
    }
    async getFileMetadata(req, res) {
        const { fileStorageId } = req.params;
        try {
            const file = await this.fileStorageService.getFileInfo(fileStorageId);
            if (!file) {
                res.status(404).send({
                    error: "File not found"
                });
                return;
            }
            res.send({
                fileStorageId: file.fileStorageId,
                fileName: file.fileName,
                fileFormat: file.fileFormat,
                fileSize: file.fileSize,
                fileHash: file.fileHash,
                createdAt: file.createdAt,
                thumbnailCount: file.thumbnailCount,
                thumbnailsUrl: file.thumbnailCount > 0 ? `/api/file-storage/${file.fileStorageId}/thumbnail/0` : null,
                metadata: file.metadata
            });
        } catch (error) {
            this.logger.error(`Failed to get file metadata for ${fileStorageId}: ${error}`);
            res.status(500).send({
                error: "Failed to get file metadata"
            });
        }
    }
    async deleteFile(req, res) {
        const { fileStorageId } = req.params;
        try {
            await this.fileStorageService.deleteFile(fileStorageId);
            this.logger.log(`Deleted file ${fileStorageId}`);
            res.send({
                message: "File deleted successfully",
                fileStorageId
            });
        } catch (error) {
            this.logger.error(`Failed to delete file ${fileStorageId}: ${error}`);
            res.status(500).send({
                error: "Failed to delete file"
            });
        }
    }
    async analyzeFile(req, res) {
        const { fileStorageId } = req.params;
        try {
            const filePath = this.fileStorageService.getFilePath(fileStorageId);
            const fileExists = await this.fileStorageService.fileExists(fileStorageId);
            if (!fileExists) {
                res.status(404).send({
                    error: "File not found"
                });
                return;
            }
            this.logger.log(`Analyzing file: ${fileStorageId}`);
            const existingMetadata = await this.fileStorageService.loadMetadata(fileStorageId);
            const analysisResult = await this.fileAnalysisService.analyzeFile(filePath);
            const metadata = analysisResult.metadata;
            const thumbnails = analysisResult.thumbnails;
            this.logger.log(`Analysis complete for ${fileStorageId}: format=${metadata.fileFormat}, layers=${metadata.totalLayers}, time=${metadata.gcodePrintTimeSeconds}s, thumbnails=${thumbnails.length}`);
            const fileHash = await this.fileStorageService.calculateFileHash(filePath);
            const originalFileName = existingMetadata?._originalFileName || fileStorageId;
            metadata.fileName = originalFileName;
            let thumbnailMetadata = [];
            if (thumbnails.length > 0) {
                thumbnailMetadata = await this.fileStorageService.saveThumbnails(fileStorageId, thumbnails);
                this.logger.log(`Saved ${thumbnailMetadata.length} thumbnails for ${fileStorageId}`);
            }
            await this.fileStorageService.saveMetadata(fileStorageId, metadata, fileHash, originalFileName, thumbnailMetadata);
            res.send({
                message: "File analyzed successfully",
                fileStorageId,
                metadata,
                thumbnailCount: thumbnails.length
            });
        } catch (error) {
            this.logger.error(`Failed to analyze file ${fileStorageId}: ${error}`);
            res.status(500).send({
                error: `Failed to analyze file: ${error}`
            });
        }
    }
    async getThumbnail(req, res) {
        const { fileStorageId, index } = req.params;
        const thumbnailIndex = Number.parseInt(index);
        if (Number.isNaN(thumbnailIndex)) {
            res.status(400).send({
                error: "Invalid thumbnail index"
            });
            return;
        }
        try {
            const thumbnail = await this.fileStorageService.getThumbnail(fileStorageId, thumbnailIndex);
            if (!thumbnail) {
                res.status(404).send({
                    error: "Thumbnail not found"
                });
                return;
            }
            const isJPG = thumbnail[0] === 0xFF && thumbnail[1] === 0xD8;
            let contentType = 'image/png';
            if (isJPG) contentType = 'image/jpeg';
            res.setHeader('Content-Type', contentType);
            res.setHeader('Cache-Control', 'public, max-age=3600');
            res.setHeader('ETag', `"${fileStorageId}-${thumbnailIndex}"`);
            res.send(thumbnail);
        } catch (error) {
            this.logger.error(`Failed to get thumbnail ${thumbnailIndex} for ${fileStorageId}: ${error}`);
            res.status(500).send({
                error: "Failed to get thumbnail"
            });
        }
    }
    async uploadFile(req, res) {
        try {
            const acceptedExtensions = [
                '.gcode',
                '.3mf',
                '.bgcode'
            ];
            const files = await this.multerService.multerLoadFileAsync(req, res, acceptedExtensions, true);
            if (!files?.length) {
                res.status(400).send({
                    error: "No file uploaded"
                });
                return;
            }
            if (files.length > 1) {
                res.status(400).send({
                    error: "Only 1 file can be uploaded at a time"
                });
                return;
            }
            const file = files[0];
            const ext = (0, _nodepath.extname)(file.originalname);
            const tempPathWithExt = file.path + ext;
            try {
                (0, _nodefs.copyFileSync)(file.path, tempPathWithExt);
                const fileHash = await this.fileStorageService.calculateFileHash(tempPathWithExt);
                this.logger.log(`Analyzing file: ${file.originalname} (ext: ${ext})`);
                const analysisResult = await this.fileAnalysisService.analyzeFile(tempPathWithExt);
                const metadata = analysisResult.metadata;
                const thumbnails = analysisResult.thumbnails;
                this.logger.log(`Analysis complete: format=${metadata.fileFormat}, layers=${metadata.totalLayers}, ` + `time=${metadata.gcodePrintTimeSeconds}s, filament=${metadata.filamentUsedGrams}g, ` + `thumbnails=${thumbnails.length}`);
                const fileStorageId = await this.fileStorageService.saveFile(file, fileHash);
                this.logger.log(`Uploaded file ${file.originalname} as ${fileStorageId}`);
                let thumbnailMetadata = [];
                if (thumbnails.length > 0) {
                    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);
                this.logger.log(`Saved metadata JSON for ${fileStorageId}`);
                res.send({
                    message: "File uploaded successfully",
                    fileStorageId,
                    fileName: file.originalname,
                    fileSize: file.size,
                    fileHash,
                    metadata,
                    thumbnailCount: thumbnails.length
                });
            } finally{
                if ((0, _nodefs.existsSync)(tempPathWithExt)) {
                    (0, _nodefs.unlinkSync)(tempPathWithExt);
                }
            }
        } catch (error) {
            this.logger.error(`Failed to upload file: ${error}`);
            res.status(500).send({
                error: "Failed to upload file"
            });
        }
    }
}
_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)
], FileStorageController.prototype, "listFiles", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:fileStorageId"),
    _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)
], FileStorageController.prototype, "getFileMetadata", null);
_ts_decorate([
    (0, _awilixexpress.DELETE)(),
    (0, _awilixexpress.route)("/:fileStorageId"),
    _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)
], FileStorageController.prototype, "deleteFile", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/:fileStorageId/analyze"),
    _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)
], FileStorageController.prototype, "analyzeFile", null);
_ts_decorate([
    (0, _awilixexpress.GET)(),
    (0, _awilixexpress.route)("/:fileStorageId/thumbnail/:index"),
    _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)
], FileStorageController.prototype, "getThumbnail", null);
_ts_decorate([
    (0, _awilixexpress.POST)(),
    (0, _awilixexpress.route)("/upload"),
    _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)
], FileStorageController.prototype, "uploadFile", null);
FileStorageController = _ts_decorate([
    (0, _awilixexpress.route)(_serverconstants.AppConstants.apiRoute + "/file-storage"),
    (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 _filestorageservice.FileStorageService === "undefined" ? Object : _filestorageservice.FileStorageService,
        typeof _multerservice.MulterService === "undefined" ? Object : _multerservice.MulterService,
        typeof _fileanalysisservice.FileAnalysisService === "undefined" ? Object : _fileanalysisservice.FileAnalysisService
    ])
], FileStorageController);

//# sourceMappingURL=file-storage.controller.js.map