/* eslint-disable no-console */
/*
 Used as a router for Uploads Providers
 */
'use strict';
//local libs
const UtilHttpStatus = require('../../shared/utils/UtilHttpStatus');
const UtilDocumentId = require('../../shared/utils/UtilDocumentId');
const UtilFileReference = require('../utils/UtilFileReference');
const UtilError = require('../utils/UtilError');
const UtilFileUploadData = require('../utils/UtilFileUploadData');
const UtilPackage = require('../utils/UtilPackage');
const { getSubDirectory } = require('../file/FileSettings');
//globals
const provider = require('../uploads/providers/PlainDirectoryProvider');
var mime = require('mime-types');

exports.uploadFiles = async function(req, res) {
    try {
        let file = req.file || req.body.file;
        const mimetype =  file.mimetype || req.body.mimetype;
        const fileType =  mime.extension(mimetype).toUpperCase();

        if(!UtilFileUploadData.whiteListed(fileType)){
            throw new UtilError.InvalidRequestError('File type not allowed.');
        }

        const basePath = getSubDirectory();
        const fileName = file.originalname ||  req.body.originalname;
        const fileReferenceTemplateId = req.body.fileReferenceTemplateId;
        // using 'filename' from multer response file as fileNo
        // so we won't have to rename the file on every upload
        const fileNo = file.filename || req.body.fileNo;


        //prepare data for creating file reference
        const meta = {

            file : {
                fileNo,
                fileName : fileName,
                fileType : fileType,
                basePath
            },

            parent : {//parent document id
                documentId : req.body.documentId,
                name: req.body.documentName
            },

            ownerUserId: req.user.documentId

        };

        if(mimetype){
            meta.file.ext = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length);
            meta.file.mimeDetailsObj = {
                contentType : mimetype
            };
        }

        //create file reference
        await UtilFileReference.createReferenceDocument(meta.file, meta.parent, meta.ownerUserId, fileReferenceTemplateId);

        res.json({ fileNo, basePath, fileType });
    }catch(err){

        logger.error('Error in file upload: ' + err.message);

        const httpStatus = err.httpStatusCode ? err.httpStatusCode : UtilHttpStatus.INTERNAL_SERVER_ERROR;
        res.status(httpStatus).send(err.message);

        if(httpStatus === UtilHttpStatus.INTERNAL_SERVER_ERROR){
            // for server errors, display the full stack trace
            throw err;
        }
    }

};

// req.params.fileNo
// todo: make async
exports.getFile = function(req, res){

    var fileRequest = null;

    Promise.resolve().then(function () {

        return UtilFileReference.fetchReferenceDocument(req.params.fileNo, req.user.documentId);

    }).then(function (referenceDocument) {

        if(!referenceDocument){
            throw new UtilError.NotFoundError("File not found.");
        }

        var fileFieldName = UtilFileReference.getFileFieldName();

        if(!fileFieldName){
            throw new UtilError.ServerError("Field name for files not set in fileReference configuration.");
        }else if(!referenceDocument[fileFieldName]){
            throw new UtilError.ServerError("Outdated file reference document or invalid file reference config.");
        }

        //File reference is an array because it needed to be displayed in an uploader component.
        var fileReference = referenceDocument[fileFieldName][0];

        fileRequest = {
            fileNo: req.params.fileNo,
            fileName: fileReference.fileName,
            basePath: fileReference.basePath
        };

        if(fileReference.mimeDetailsObj){
            fileRequest.mime = fileReference.mimeDetailsObj.contentType;
        }

        return new Promise(function (resolve, reject) {
            provider.getFile(fileRequest, function (err, fileInfo) {
                if(err){
                    reject(err);
                }else{
                    resolve(fileInfo);
                }
            });
        });

    }).then(function (fileInfo) {

        if(!fileInfo){
            res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send('Upload provider did not work properly.');
            return;
        }

        //default headers
        res.setHeader('Content-Disposition', 'inline; filename=' + encodeURIComponent(fileRequest.fileName));

        //IE needs to receive the right content type to display images.
        var mime = fileRequest.mime;

        if(mime){
            res.setHeader('content-type', mime);
            res.sendFile(fileInfo.filePath);
        } else {
            //read file to get an idea of its contents; returns meta = {ext, mime}
            UtilFileUploadData.pathFileType(fileInfo.filePath, function(err, meta){

                if(!err && meta){
                    res.setHeader('content-type', meta.mime);
                }

                res.sendFile(fileInfo.filePath);

            });
        }
    }).catch(function processProviderErr(e){
        
        if(e instanceof UtilError.InvalidRequestError){
            res.status(UtilHttpStatus.BAD_REQUEST).send(e.message);
        }else if(e instanceof UtilError.NotFoundError){
            res.status(UtilHttpStatus.NOT_FOUND).send(e.message);
        }else if(e instanceof UtilError.NoPermissionError){
            res.status(UtilHttpStatus.FORBIDDEN).send(e.message);
        }else {
            res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send(e.message);
        }

    });

};

// req.params.fid
exports.deleteFile = async function(req, res){
    var fid = req.param('fid');
    try {
        await UtilFileReference.destroyFileReference(fid, req.user.documentId);
        res.status(UtilHttpStatus.OK).send();
    }catch (err) {
        logger.error(`Failed to destroy file reference for ${fid}.`);
        logger.error(err);
        res.status(UtilHttpStatus.INTERNAL_SERVER_ERROR).send('Failed to remove file.');
    }
};

exports.provider = provider;


