"use strict";
var __decorate = (this && this.__decorate) || function (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;
};
var FileServer_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileServerService = void 0;
const rxjs_1 = require("rxjs");
const crypto = require("crypto");
const URL = require("url");
const fs = require("fs");
//const TransferPromiseQueue = require("./TransferPromiseQueue");
const promiseQueue_1 = require("../common/promiseQueue");
const Utils_1 = require("../common/Utils");
const ErrorManager_1 = require("../common/ErrorManager");
//const blobUtil = require("blob-util");
//const Blob = require("blob");
const Utils_2 = require("../common/Utils");
const GenericService_1 = require("./GenericService");
const LOG_ID = "FileServer/SVCE - ";
const API_ID = "API_CALL - ";
const ONE_KILOBYTE = 1024;
const ONE_MEGABYTE = 1024 * 1024;
const ONE_GIGABYTE = 1024 * 1024 * 1024;
let FileServer = FileServer_1 = 
/**
* @module
* @name FileStorage
 * @version 2.42.0-lts.4 - Documentation generated on 2026/04/24T11:38:22.926Z
* @public
* @description
*      This service manage files on server side <br>
*/
class FileServer extends GenericService_1.GenericService {
    static getClassName() { return 'FileServer'; }
    getClassName() { return FileServer_1.getClassName(); }
    static getAccessorName() { return 'fileServer'; }
    getAccessorName() { return FileServer_1.getAccessorName(); }
    constructor(_core, _eventEmitter, _logger, _startConfig) {
        super(_logger, LOG_ID, _eventEmitter);
        this.setLogLevels(this);
        this._startConfig = _startConfig;
        this._eventEmitter = _eventEmitter;
        this._xmpp = null;
        this._rest = null;
        this._s2s = null;
        this._options = {};
        this._useXMPP = false;
        this._useS2S = false;
        this._logger = _logger;
        this._capabilities = null;
        this.transferPromiseQueue = null;
        this._fileStorageService = null;
        this._core = _core;
    }
    get capabilities() {
        let that = this;
        return new Promise((resolve, reject) => {
            if (!that._capabilities) {
                if (that._rest) {
                    that._rest.getServerCapabilities().then((capabilities) => {
                        that._capabilities = capabilities;
                        //that.transferPromiseQueue = new TransferPromiseQueue(that._logger);
                        resolve(this._capabilities);
                    }).catch(() => {
                        return reject();
                    });
                }
                else {
                    return reject();
                }
                return;
            }
            resolve(that._capabilities);
        });
    }
    start(_options) {
        let that = this;
        that.initStartDate();
        return new Promise(function (resolve, reject) {
            try {
                that._xmpp = that._core._xmpp;
                that._rest = that._core._rest;
                that._options = _options;
                that._s2s = that._core._s2s;
                that._useXMPP = that._options.useXMPP;
                that._useS2S = that._options.useS2S;
                that._fileStorageService = that._core.fileStorage;
                that.setStarted();
                resolve(undefined);
            }
            catch (err) {
                return reject(err);
            }
        });
    }
    stop() {
        let that = this;
        return new Promise(function (resolve, reject) {
            try {
                that._xmpp = null;
                that._rest = null;
                that.setStopped();
                resolve(undefined);
            }
            catch (err) {
                return reject(err);
            }
        });
    }
    init(useRestAtStartup) {
        let that = this;
        return new Promise(async (resolve, reject) => {
            if (useRestAtStartup) {
                await that.capabilities.then((result) => {
                    that.setInitialized();
                }).catch(() => {
                    that.setInitialized();
                });
                //                resolve(capa);
            }
            else {
                that.setInitialized();
            }
            resolve(null);
        });
    }
    /**
     *
     * @private
     * @description
     *    Method retrieve data from server using range request mecanism (RFC7233)
     * @returns {Object} structure containing the response data from server and the index
     *
     * @param {string} url (required) server url for request
     * @param {number} minRange (required) minimum value of range
     * @param {number} maxRange (required) maximum value of range
     * @param {number} index (required) index of the part. Used to re-assemble the data     *
     */
    getPartialDataFromServer(url, minRange, maxRange, index) {
        return this._rest.getPartialDataFromServer(url, minRange, maxRange, index);
    }
    getPartialBufferFromServer(url, minRange, maxRange, index) {
        return this._rest.getPartialBufferFromServer(url, minRange, maxRange, index);
    }
    /**
     * @method getBufferFromUrlWithOptimization
     * @description
     * Method creates buffer from a file retrieved from server using optimization (range request) whenever necessary
     *
     * @param {string} url (required) server url for request
     * @param {string} mime (required) Mime type of the blob to be created
     * @param {number} fileSize=0 (optional) size of file to be retrieved. Default: 0
     * @param {string} fileName (optional) name of file to be downloaded
     * @param {string} uploadedDate
     * @returns {Buffer} Buffer created from data received from server
     *
     */
    getBufferFromUrlWithOptimization(url, mime, fileSize = 0, fileName, uploadedDate) {
        let that = this;
        if (fileSize === void 0) {
            fileSize = 0;
        }
        if (fileName === void 0) {
            fileName = "";
        }
        if (uploadedDate === void 0) {
            uploadedDate = "";
        }
        if (uploadedDate.length !== 0) {
            url += "?update=" + crypto.createHash("md5").update(uploadedDate).digest("hex");
        }
        let _url = url.startsWith("http") ? URL.parse(url).path : url;
        return new Promise((resolve, reject) => {
            this.capabilities.then((capabilities) => {
                if (Boolean(capabilities.maxChunkSizeDownload) && fileSize !== 0 && fileSize > capabilities.maxChunkSizeDownload) {
                    let range = capabilities.maxChunkSizeDownload;
                    let minRange = 0;
                    let maxRange = range - 1;
                    let repetition = Math.ceil(fileSize / range);
                    let bufferArray = new Array(repetition);
                    let promiseArray = [];
                    for (let i = 0; repetition > 0; i++, repetition--, minRange += range, maxRange += range) {
                        promiseArray.push(this.getPartialDataFromServer(_url, minRange, maxRange, i).then((response) => {
                            bufferArray[response.index] = response.data;
                            return (response.data);
                        }));
                    }
                    Promise.all(promiseArray)
                        .then(() => {
                        let buffer = Buffer.concat(bufferArray);
                        that._logger.log(that.INFO, LOG_ID + "(getBufferFromUrlWithOptimization) success");
                        resolve(buffer);
                    }, (error) => {
                        that._logger.log(that.ERROR, LOG_ID + "(getBufferFromUrlWithOptimization) Error.");
                        that._logger.log(that.INTERNALERROR, LOG_ID + "(getBufferFromUrlWithOptimization) Error : ", error);
                        return reject(error);
                    });
                }
                else {
                    resolve(that._rest.getFileFromUrl(_url));
                }
            });
        });
    }
    /**
     * @method getFileFromUrlWithOptimization
     * @description
     * Method creates buffer from a file retrieved from server using optimization (range request) whenever necessary
     *
     * @param {string} destFile
     * @param {string} url (required) server url for request
     * @param {string} mime (required) Mime type of the blob to be created
     * @param {number} fileSize=0 (optional) size of file to be retrieved. Default: 0
     * @param {string} fileName (optional) name of file to be downloaded
     * @param {string} uploadedDate (optional) date of the upload
     * @returns {Buffer} Buffer created from data received from server
     *
     */
    getFileFromUrlWithOptimization(destFile, url, mime, fileSize = 0, fileName, uploadedDate) {
        let that = this;
        if (fileSize === void 0) {
            fileSize = 0;
        }
        if (fileName === void 0) {
            fileName = "";
        }
        if (uploadedDate === void 0) {
            uploadedDate = "";
        }
        if (uploadedDate.length !== 0) {
            url += "?update=" + crypto.createHash("md5").update(uploadedDate).digest("hex");
        }
        let _url = url.startsWith("http") ? URL.parse(url).path : url;
        let stream = fs.createWriteStream(destFile, {
            flags: "a"
        });
        return new Promise((resolve, reject) => {
            this.capabilities.then((capabilities) => {
                if (Boolean(capabilities.maxChunkSizeDownload) && fileSize !== 0 && fileSize > capabilities.maxChunkSizeDownload) {
                    let range = capabilities.maxChunkSizeDownload;
                    let minRange = 0;
                    let maxRange = range - 1;
                    let repetition = Math.ceil(fileSize / range);
                    let blobArray = new Array(repetition);
                    let promiseArray = [];
                    for (let i = 0; repetition > 0; i++, repetition--, minRange += range, maxRange += range) {
                        promiseArray.push(this.getPartialDataFromServer(_url, minRange, maxRange, i)
                            .then((response) => {
                            blobArray[response.index] = response.data;
                            return (response.data);
                        }));
                    }
                    Promise.all(promiseArray)
                        .then(() => {
                        let buffer = Buffer.concat(blobArray);
                        that._logger.log(that.INFO, LOG_ID + "(getFileFromUrlWithOptimization) success");
                        resolve(buffer);
                    }, (error) => {
                        that._logger.log(that.ERROR, LOG_ID + "(getFileFromUrlWithOptimization) Error.");
                        that._logger.log(that.INTERNALERROR, LOG_ID + "(getFileFromUrlWithOptimization) Error : ", error);
                        return reject(error);
                    });
                }
                else {
                    resolve(that._rest.getFileFromUrl(_url));
                }
            });
        });
    }
    /***
     * @private
     * @param fileDescriptor
     * @param large
     */
    async getBlobThumbnailFromFileDescriptor(fileDescriptor, large = false) {
        /*
                if (fileDescriptor.thumbnail.isThumbnailAvailable() ||
                    (fileDescriptor.isImage() && fileDescriptor.size < (20 * this.ONE_KILOBYTE)) ) {
        
                    // Check if a request for this thumbnail is already lauched
                    let existingPromise = this.thumbnailPromises[fileDescriptor.id];
                    if (existingPromise) {
                        this.$log.info("[FileServerService] getBlobThumbnailFromFileDescriptor " + fileDescriptor.id + " already lauched");
                        return existingPromise.promise;
                    }
        
                    // Create the defered object
                    let defered = this.$q.defer();
                    this.thumbnailPromises[fileDescriptor.id] = defered;
        
                    // Forge the thumbnail url
                    let url = fileDescriptor.url;
                    if (fileDescriptor.thumbnail.isThumbnailAvailable() && fileDescriptor.size >= (20 * this.ONE_KILOBYTE)) {
                        if (large) { url += "?thumbnail500=true"; }
                        else { url += "?thumbnail=true"; }
                    }
                    else if (fileDescriptor.uploadedDate) { url += "?update=" + MD5.hexdigest(fileDescriptor.uploadedDate); }
        
                    // Get the thumbnail blob
                    this.getBlobFromUrl(url, fileDescriptor.typeMIME, fileDescriptor.size, fileDescriptor.fileName)
                        .then((blob) => {
                            fileDescriptor.previewBlob = blob;
        
                            this.$rootScope.$broadcast("ON_FILE_TRANSFER_EVENT", {
                                result: "success", type: "download",
                                fileDesc: fileDescriptor});
                            delete this.thumbnailPromises[fileDescriptor.id];
                            defered.resolve(blob);
                        })
                        .catch((error) => {
                            this.$rootScope.$broadcast("ON_FILE_TRANSFER_EVENT", {
                                result: "failure", type: "download", message: error.message,
                                fileDesc: fileDescriptor});
                            delete this.thumbnailPromises[fileDescriptor.id];
                            defered.reject(error);
                        });
        
                    return defered.promise;
                }
                else { return this.$q.reject(); }
        
         */
    }
    ;
    /**
     * @description
     * Method sends data file to server
     *
     * @private
     * @param {string} fileId (required) file descriptor ID of file to be sent
     * @param {string} filePath (required) file path to file to be sent
     * @param {string} mime (required) mime type of file
     * @returns {Promise<FileDescriptor>} file descriptor data received as response from server or http error response
     *
     */
    _uploadAFile(fileId, filePath, mime) {
        let that = this;
        return new Promise((resolve, reject) => {
            let fileDescriptor = that._fileStorageService.getFileDescriptorById(fileId);
            if (fileDescriptor) {
                fileDescriptor.state = "uploading";
            }
            let stream = fs.createReadStream(filePath);
            //let buffer = new Buffer(ONE_MEGABYTE);
            /*
                        let myWritableStreamBuffer = new streamBuffers.WritableStreamBuffer({
                            initialSize: (1000 * 1024),   // start at 100 kilobytes.
                            incrementAmount: (100 * 1024) // grow by 10 kilobytes each time buffer overflows.
                        });
            */
            //stream.pipe(myWritableStreamBuffer);
            //            stream.pipe(buffer)
            that._rest.uploadAStream(fileId, stream).then((response) => {
                //let fileDescResponse = response.data.data;
                let newFileDescriptor = that._fileStorageService.getFileDescriptorById(fileId);
                if (newFileDescriptor) {
                    newFileDescriptor.state = "uploaded";
                }
                that._logger.log(that.INFO, LOG_ID + "(_uploadAFile) success");
                // this.$rootScope.$broadcast("ON_FILE_TRANSFER_EVENT", {
                //     result: "success",
                //     type: "upload",
                //     url: this.portalURL + "/" + fileId,
                //     fileId: fileId,
                //     mime: mime,
                //     filename: file.name,
                //     filesize: file.size
                // });
                // this._fileStorageService.orderDocuments();
                resolve(newFileDescriptor);
            }).catch((errorResponse) => {
                // let error = this.errorHelperService.handleError(errorResponse);
                // this.$rootScope.$broadcast("ON_FILE_TRANSFER_EVENT", {
                //     result: "failure",
                //     type: "upload",
                //     url: this.portalURL + "/" + fileId,
                //     fileId: fileId,
                //     mime: mime,
                //     filename: file.name,
                //     filesize: file.size
                // });
                that._logger.log(that.ERROR, LOG_ID + "(_uploadAFile) error.");
                that._logger.log(that.INTERNALERROR, LOG_ID + "(_uploadAFile) error : ", errorResponse);
                return reject(errorResponse);
            });
        });
    }
    /**
     * @description
     * Method sends data to server using range request mecanism (RFC7233)
     *
     * @private
     * @param {string} fileId (required) file descriptor ID of file to be sent
     * @param {Buffer} file (required) file to be sent
     * @param {number} index (required) index of the part. Used to indicate the part number to the server
     * @returns {Promise<{}>} file descriptor data received as response from server or http error response
     *
     */
    _sendPartialDataToServer(fileId, file, index) {
        let that = this;
        return new Promise((resolve, reject) => {
            that._rest.sendPartialDataToServer(fileId, file, index).then((response) => {
                let filedescriptor = response.data;
                that._logger.log(that.INFO, LOG_ID + "(_sendPartialDataToServer) sendPartialDataToServer success");
                resolve(filedescriptor);
            }, (errorResponse) => {
                //let error = this.errorHelperService.handleError(errorResponse);
                that._logger.log(that.ERROR, LOG_ID + "(_sendPartialDataToServer) Error.");
                that._logger.log(that.INTERNALERROR, LOG_ID + "(_sendPartialDataToServer) Error : ", errorResponse);
                return reject(errorResponse);
            });
        });
    }
    /**
     * @description
     * Upload File ByChunk progressCallback callback is displayed as part of the Requester class.
     * @callback uploadAFileByChunk~progressCallback
     * @param {FileDescriptor} fileDescriptor
     */
    /**
     * @method uploadAFileByChunk
     * Method sends data to server using range request mecanism (RFC7233)
     *
     * @private
     * @param {FileDescriptor} fileDescriptor (required) file descriptor Object of file to be sent
     * @param {string} filePath (required) filePath of the file to be sent
//     * @param {uploadAFileByChunk~progressCallback} progressCallback (required) initial size of whole file to be sent before partition
     * @returns {Promise<{FileDescriptor}>} file descriptor data received as response from server or http error response
     *
     */
    async uploadAFileByChunk(fileDescriptor, filePath /*, progressCallback */) {
        let that = this;
        let promiseQueue = (0, promiseQueue_1.createPromiseQueue)(that._logger);
        let fileStats = fs.statSync(filePath);
        //let range = ONE_MEGABYTE;
        let range = (await that.capabilities).maxChunkSizeUpload;
        if (range < fileStats.size) {
            if (fileStats.size >= 100 * range) {
                range = (fileStats.size / 100) + this.ONE_KILOBYTE;
                that._logger.log(that.DEBUG, LOG_ID + "(uploadAFileByChunk) changing chunk size: " + range);
            }
            let deferred = new Utils_1.Deferred();
            fileDescriptor.chunkTotalNumber = Math.ceil(fileStats.size / range);
            fileDescriptor.chunkPerformed = 0;
            fileDescriptor.chunkPerformedPercent = 0;
            fileDescriptor.state = "uploading";
            //let promiseArray = [];
            let fd = fs.openSync(filePath, "r+");
            let partialSent = (promiseDeferred, blob, i) => {
                //let promiseArrayDeferred = new Deferred();
                that._sendPartialDataToServer(fileDescriptor.id, blob, i)
                    .then((response) => {
                    fileDescriptor.chunkPerformed++;
                    fileDescriptor.chunkPerformedPercent = 100 * fileDescriptor.chunkPerformed / fileDescriptor.chunkTotalNumber;
                    // progressCallback(fileDescriptor);
                    return promiseDeferred.resolve(response);
                })
                    .catch((error) => {
                    that._logger.log(that.ERROR, LOG_ID + "(uploadAFileByChunk) error on chunk upload.");
                    that._logger.log(that.INTERNALERROR, LOG_ID + "(uploadAFileByChunk) error on chunk upload : ", error);
                    return promiseDeferred.reject(error);
                });
                return promiseDeferred.promise;
            };
            for (let i = 0, minRange = 0, maxRange = range - 1, repetition = Math.ceil(fileStats.size / range); repetition > 0; i++, repetition--, minRange += range, maxRange += range) {
                let max = maxRange < fileStats.size ? maxRange + 1 : fileStats.size;
                let sizeToRead = max - minRange;
                let buf = new Buffer(sizeToRead);
                that._logger.log(that.DEBUG, LOG_ID + "(uploadAFileByChunk) sizeToRead=", sizeToRead, ", minRange : ", minRange, ", max : ", max, ", buff.byteLength : ", buf.byteLength);
                let promiseDeferred = new Utils_1.Deferred();
                //promiseArray.push(promiseDeferred.promise);
                promiseQueue.add(() => {
                    fs.readSync(fd, buf, 0, sizeToRead, null);
                    partialSent(promiseDeferred, buf, i);
                    return promiseDeferred.promise;
                });
            }
            /* let promisesCompletion = () => {
                 this._rest.sendPartialFileCompletion(fileDescriptor.id)
                     .then(
                         (response) => {
                             that._logger.log(that.INFO, LOG_ID + "(uploadAFileByChunk) success");
                             fileDescriptor.state = "uploaded";
                             fileDescriptor.chunkPerformed = 0;
                             fileDescriptor.chunkTotalNumber = 0;
                             fileDescriptor.chunkPerformedPercent = 0;
                             // progressCallback(fileDescriptor);
                             deferred.resolve(fileDescriptor);
                         })
                     .catch((errorResponse) => {
                         deferred.reject(errorResponse);
                     });
             };
             let promisesReject = (errorResponse) => {
                 deferred.reject(errorResponse);
             };
             that.transferPromiseQueue.addPromiseArray(promiseArray, promisesCompletion, promisesReject);
             // */
            promiseQueue.add(() => {
                return this._rest.sendPartialFileCompletion(fileDescriptor.id)
                    .then((response) => {
                    that._logger.log(that.INFO, LOG_ID + "(uploadAFileByChunk) success");
                    fileDescriptor.state = "uploaded";
                    fileDescriptor.chunkPerformed = 0;
                    fileDescriptor.chunkTotalNumber = 0;
                    fileDescriptor.chunkPerformedPercent = 0;
                    // progressCallback(fileDescriptor);
                    deferred.resolve(fileDescriptor);
                })
                    .catch((errorResponse) => {
                    return deferred.reject(errorResponse);
                });
            });
            // */
            return deferred.promise;
        }
        // Fallback if capabilities retrieval fails or file is small enough to upload the whole file in one go
        // progressCallback(fileDescriptor);
        return that._uploadAFile(fileDescriptor.id, filePath, fileDescriptor.typeMIME)
            .then((response) => {
            that._logger.log(that.INFO, LOG_ID + "(uploadAFileByChunk) uploadAFile success");
            // progressCallback(fileDescriptor);
            return Promise.resolve(fileDescriptor);
        });
    }
    isTransferInProgress() {
        return this.transferPromiseQueue.isTransferInProgress();
    }
    cancelAllTransfers() {
        this.transferPromiseQueue.cancelAllTransfers();
    }
    /**
     * @method getBlobFromUrlWithOptimization
     * @description
     * Method creates blob from a file retrieved from server using optimization (range request) whenever necessary
     *
     * @param {string} url (required) server url for request
     * @param {string} mime (required) Mime type of the blob to be created
     * @param {number} fileSize=0 (optional) size of file to be retrieved. Default: 0
     * @param {string} fileName (optional) name of file to be downloaded
     * @param {string} uploadedDate
     * @returns {Promise<{
     *                          buffer : Array<any>,
     *                           type: string, // mime type
     *                           fileSize: number,
     *                           fileName: string
     *                       }>} Object created from data received from server.
     */
    async getBlobFromUrlWithOptimization(url, mime, fileSize = 0, fileName, uploadedDate) {
        let that = this;
        if (fileSize == null) {
            fileSize = 0;
        }
        if (fileName == null) {
            fileName = "";
        }
        if (uploadedDate == null) {
            uploadedDate = "";
        }
        if (uploadedDate.length !== 0) {
            // NEED TO BE CORREDTED TO BE USED IN NODE RAINBOW SDK  url += "?update=" + MD5.hexdigest(uploadedDate);
        }
        if (!!(await that.capabilities).maxChunkSizeDownload && fileSize !== 0 && fileSize > (await that.capabilities).maxChunkSizeDownload) {
            return new Promise(async (resolve, reject) => {
                let range = (await that.capabilities).maxChunkSizeDownload;
                if (range > (ONE_MEGABYTE * 10)) {
                    range = (ONE_MEGABYTE * 10);
                }
                let minRange = 0;
                let maxRange = range - 1;
                let repetition = Math.ceil(fileSize / range);
                let numberOfChunks = Math.ceil(fileSize / range);
                let blobArray = new Array(repetition);
                that._logger.log(that.INTERNAL, LOG_ID + "(getBlobFromUrlWithOptimization) - range : ", range, ", fileSize : ", fileSize, ", repetition : ", repetition, ", ONE_MEGABYTE : ", ONE_MEGABYTE, ", numberOfChunks : ", numberOfChunks);
                that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) : " + repetition + " chunks to be downloaded");
                let promiseArray = [];
                for (let i = 0; repetition > 0; i++, repetition--, minRange += range, maxRange += range) {
                    that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - get partial buffer, iter : ", i, ", minRange : ", minRange, ", maxRange : ", maxRange);
                    promiseArray.push(
                    //let result = await that.getPartialDataFromServer(url, minRange, maxRange, i)
                    //let result = await that.getPartialBufferFromServer(url, minRange, maxRange, i)
                    //let result = await that.getPartialBufferFromServer(url, minRange, maxRange, i)
                    that.getPartialBufferFromServer(url, minRange, maxRange, i)
                        .then((response) => {
                        let index = response['index'];
                        that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - getPartialBufferFromServer iter ", i, "/", numberOfChunks, " succeed! Store at index : ", index);
                        blobArray[index] = response['data'];
                        //return (response['data']);
                        return ({ "code": 0, "label": "OK" });
                    }).catch((error) => {
                        that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrlWithOptimization) - Error getPartialBufferFromServer iter : ", i, "/", numberOfChunks, " error : ", error);
                    }));
                    //that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - getPartialBufferFromServer iter : ", i, "/", numberOfChunks,", result : ", result);
                    // repetition =0;
                    await (0, Utils_1.pause)(20);
                }
                that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - wait for the ", numberOfChunks, " chunks to be downloaded!");
                //promiseArray.push(Promise.resolve());
                Promise.all(promiseArray)
                    .then(() => {
                    /* NEED TO BE CORREDTED TO BE USED IN NODE RAINBOW SDK
                     let blob = new Blob(blobArray,
                        { type: mime });
                    that._logger.log(that.INFO, LOG_ID + "getBlobFromUrlWithOptimization success");

                    resolve(blob);
                    */
                    that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - all the ", numberOfChunks, " chunks downloaded!");
                    let blob = {
                        buffer: blobArray,
                        type: mime,
                        fileSize: fileSize,
                        fileName: fileName
                    }; // */
                    resolve(blob);
                }, (errorResponse) => {
                    let errorMessage = "(getBlobFromUrlWithOptimization) failure : " + errorResponse.message;
                    that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrlWithOptimization) Error.");
                    that._logger.log(that.INTERNALERROR, LOG_ID + "(getBlobFromUrlWithOptimization) : ", errorResponse);
                    return reject(ErrorManager_1.ErrorManager.getErrorManager().OTHERERROR(errorMessage, errorMessage));
                    /*
                    let error = this.errorHelperService.handleError(errorResponse);

                    let errorDataObj = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(errorResponse.data)));
                    let translatedErrorMessage = that.errorHelperService.getLocalizedError(errorDataObj.errorDetailsCode);
                    that._logger.log(that.INFO, LOG_ID + "" + translatedErrorMessage ? translatedErrorMessage : error.message);
                    */
                    //reject(errorMessage);
                });
            });
        }
        else {
            return this.getBlobFromUrl(url, mime, fileSize, fileName);
        }
    }
    ;
    /**
     * @method getBlobFromUrlWithOptimizationObserver
     * @description
     * Method creates blob from a file retrieved from server using optimization (range request) whenever necessary
     *
     * @param {string} url (required) server url for request
     * @param {string} mime (required) Mime type of the blob to be created
     * @param {number} fileSize=0 (optional) size of file to be retrieved. Default: 0
     * @param {string} fileName (optional) name of file to be downloaded
     * @param {string} uploadedDate
     * @returns {Promise<Observable<any>} Observer returning a Blob created from data received from server
     *
     */
    async getBlobFromUrlWithOptimizationObserver(url, mime, fileSize = 0, fileName, uploadedDate) {
        let that = this;
        if (fileSize == null) {
            fileSize = 0;
        }
        if (fileName == null) {
            fileName = "";
        }
        if (uploadedDate == null) {
            uploadedDate = "";
        }
        if (uploadedDate.length !== 0) {
            // NEED TO BE CORREDTED TO BE USED IN NODE RAINBOW SDK  url += "?update=" + MD5.hexdigest(uploadedDate);
        }
        let maxChunkSizeDownload = (await that.capabilities).maxChunkSizeDownload; // / 80 to get alf of 1 Mo when server get us a 10Mo maxChunckSizeDownload;
        that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - maxChunkSizeDownload : " + maxChunkSizeDownload);
        // process.exit(-1);
        if (!!maxChunkSizeDownload && fileSize !== 0 && fileSize > maxChunkSizeDownload) {
            let promiseArray = [];
            let obsrv$ = rxjs_1.Observable.create(async (subject) => {
                let chunckLoaded = 0;
                let range = maxChunkSizeDownload;
                if (range > (ONE_MEGABYTE * 10)) {
                    that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) : set range to 10 Mo.");
                    range = (ONE_MEGABYTE * 10);
                } //
                let minRange = 0;
                let maxRange = range - 1;
                let repetition = Math.ceil(fileSize / range);
                let numberOfChunks = Math.ceil(fileSize / range);
                let blobArray = new Array(repetition);
                that._logger.log(that.INTERNAL, LOG_ID + "(getBlobFromUrlWithOptimization) - range : ", range, ", fileSize : ", fileSize, ", repetition : ", repetition, ", ONE_MEGABYTE : ", ONE_MEGABYTE, ", numberOfChunks : ", numberOfChunks);
                that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) : " + repetition + " chunks to be downloaded");
                for (let i = 0; repetition > 0; i++, repetition--, minRange += range, maxRange += range) {
                    that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - get partial buffer, iter : ", i, ", minRange : ", minRange, ", maxRange : ", maxRange);
                    promiseArray.push(new Promise((resolve, reject) => {
                        that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - push promise in Array iter : ", i, "/", numberOfChunks - 1 /* , ", result : ", result */);
                        //let result = await that.getPartialDataFromServer(url, minRange, maxRange, i)
                        //let result =
                        /*
                        // Start Test with out real download.
                        chunckLoaded++;
                        let index = 0;
                        that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - getPartialBufferFromServer Success iter ", i, "/", numberOfChunks - 1, " succeed! Store at index : ", index);
                        //blobArray[index] = response['data'];
                        subject.next(chunckLoaded * 100 / (numberOfChunks - 1 ) ); // Raise the percentage of loaded chunck.
                        //return (response['data']);
                        resolve ({"code": 0, "label": "OK"});
                        // End Test // */
                        that.getPartialBufferFromServer(url, minRange, maxRange, i).then((response) => {
                            chunckLoaded++;
                            let index = response['index'];
                            that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - getPartialBufferFromServer Success iter ", i, "/", numberOfChunks, " succeed! Store at index : ", index);
                            blobArray[index] = response['data'];
                            subject.next(chunckLoaded * 100 / numberOfChunks); // Raise the percentage of loaded chunck.
                            //return (response['data']);
                            resolve({ "code": 0, "label": "OK" });
                        }).catch((error) => {
                            that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrlWithOptimization) - Error getPartialBufferFromServer iter : ", i, "/", numberOfChunks, " error : ", error);
                            reject({ "code": -1, "label": "Error while retrieving the chunck " + i + "/" + numberOfChunks });
                        });
                        // */
                    }));
                    // repetition =0;
                    await (0, Utils_1.pause)(20);
                }
                that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - wait for the ", numberOfChunks, " chunks to be downloaded!");
                //promiseArray.push(Promise.resolve());
                Promise.all(promiseArray).then(() => {
                    that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrlWithOptimization) - all the ", numberOfChunks, " chunks downloaded!");
                    let blob = {
                        buffer: blobArray,
                        type: mime,
                        fileSize: fileSize,
                        fileName: fileName
                    }; // */
                    subject.next(blob);
                    subject.complete(); //blob
                }, (errorResponse) => {
                    let errorMessage = "(getBlobFromUrlWithOptimization) failure : " + errorResponse.message;
                    that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrlWithOptimization) Error.");
                    that._logger.log(that.INTERNALERROR, LOG_ID + "(getBlobFromUrlWithOptimization) : ", errorResponse);
                    subject.error(ErrorManager_1.ErrorManager.getErrorManager().OTHERERROR(errorMessage, errorMessage));
                });
            });
            return Promise.resolve(obsrv$);
        }
        else {
            let obsrv$ = rxjs_1.Observable.create(async (subject) => {
                subject.next(1);
                that.getBlobFromUrl(url, mime, fileSize, fileName).then((blob) => {
                    subject.next(100);
                    subject.next(blob);
                    subject.complete(); //blob
                }).catch((errorResponse) => {
                    let errorMessage = "(getBlobFromUrlWithOptimization) failure : " + errorResponse.message;
                    that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrlWithOptimization) Error.");
                    that._logger.log(that.INTERNALERROR, LOG_ID + "(getBlobFromUrlWithOptimization) : ", errorResponse);
                    subject.error(ErrorManager_1.ErrorManager.getErrorManager().OTHERERROR(errorMessage, errorMessage));
                });
            });
            return Promise.resolve(obsrv$);
            //return this.getBlobFromUrl(url, mime, fileSize, fileName);
        }
    }
    ;
    /**
     * @description
     * Method creates blob from a file retrieved from server
     *
     * @private
     * @param {string} url (required) server url for request
     * @param {string} mime (required) Mime type of the blob to be created
     * @param {number} fileSize (required) size of file to be retrieved
     * @param {string} fileName (required) name of file to be downloaded
     * @returns {Promise<{
     *                          buffer : Array<any>,
     *                           type: string, // mime type
     *                           fileSize: number,
     *                           fileName: string
     *                       }>} Blob created from data received from server
     */
    getBlobFromUrl(url, mime, fileSize, fileName) {
        let that = this;
        that._logger.log(that.INFO, LOG_ID + "(getBlobFromUrl)");
        that._logger.log(that.INTERNAL, LOG_ID + "(getBlobFromUrl) : " + url);
        return new Promise((resolve, reject) => {
            /*this.$http({
                method: "GET",
                url: url,
                headers: this.authService.getRequestHeader(),
                responseType: 'arraybuffer'
            }) // */
            that._rest.getBlobFromUrl(url).then((response) => {
                /* let blob = blobUtil.createBlob([response.data],
                    { type: mime }); // */
                let blobArray = new Array(0);
                blobArray.push(response);
                let blob = {
                    buffer: blobArray,
                    type: mime,
                    fileSize: fileSize,
                    fileName: fileName
                }; // */
                /*let blob = new Blob([response.data],
                    { type: mime }); // */
                that._logger.log(that.DEBUG, LOG_ID + "(getBlobFromUrl) success");
                resolve(blob);
            }, (errorResponse) => {
                let errorMessage = "(getBlobFromUrl) failure : " + errorResponse;
                that._logger.log(that.ERROR, LOG_ID + "(getBlobFromUrl) Error.");
                that._logger.log(that.INTERNALERROR, LOG_ID + "(getBlobFromUrl) : ", errorResponse);
                let err = ErrorManager_1.ErrorManager.getErrorManager().ERROR;
                err.msg = errorMessage;
                return reject(err);
                /*
        let error = this.errorHelperService.handleError(errorResponse);

        let errorDataObj = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(errorResponse.data)));
        let translatedErrorMessage = this.errorHelperService.getLocalizedError(errorDataObj.errorDetailsCode);
        this.$log.error("" + (translatedErrorMessage) ? translatedErrorMessage : error.message);
            // */
            });
        });
    }
    /**
     * @description
     * Method retrieves user quota (capabilities) for user
    *
    * @returns {Object} user quota for user
    *
    */
    getServerCapabilities() {
        return this._rest.getServerCapabilities();
    }
};
exports.FileServerService = FileServer;
exports.FileServerService = FileServer = FileServer_1 = __decorate([
    (0, Utils_1.logEntryExit)(LOG_ID),
    (0, Utils_2.isStarted)([])
    /**
    * @module
    * @name FileStorage
     * @version 2.42.0-lts.4 - Documentation generated on 2026/04/24T11:38:22.926Z
    * @public
    * @description
    *      This service manage files on server side <br>
    */
], FileServer);
module.exports.FileServerService = FileServer;
//# sourceMappingURL=FileServerService.js.map