/* jshint node:true */

import multiparty from 'multiparty';
import safe from 'safetydance';
import timeout from 'connect-timeout';

function _mime(req) {
    const str = req.headers['content-type'] || '';
    return str.split(';')[0];
}

export default function multipart(options, forceContentType = true) {
    return function (req, res, next) {
        if (_mime(req) !== 'multipart/form-data') {
            if (forceContentType) return res.status(400).send('Invalid content-type. Expecting multipart');
            else return next();
        }

        const form = new multiparty.Form({
            uploadDir: '/tmp',
            keepExtensions: true,
            maxFieldsSize: options.maxFieldsSize || (2 * 1024), // only field size, not files
            limit: options.limit || '8mb', // file sizes
            autoFiles: true // emit files instead of emitting 'part'
        });

        // increase timeout of file uploads by default to 3 mins
        if (req.clearTimeout) req.clearTimeout(); // clear any previous installed timeout middleware

        timeout(options.timeout || (3 * 60 * 1000))(req, res, function () {
            req.fields = {};
            req.files = {};

            form.parse(req, function (error, fields, files) {
                if (error) {
                    for (const file in files) safe.fs.unlinkSync(file.path);
                    return res.status(400).send('Error parsing request');
                }
                next(null);
            });

            form.on('file', function (name, file) {
                req.files[name] = file;
            });

            form.on('field', function (name, value) {
                try {
                    req.fields[name] = JSON.parse(value); // otherwise fields.name is an array
                // eslint-disable-next-line no-unused-vars
                } catch (e) {
                    req.fields[name] = value; // otherwise fields.name is an array
                }
            });
        });
    };
};

