
const fs = require('fs');
const path = require('path');
const uuid = require('uuid/v4');

/**
 * Suggest new names for files.
 *
 * Takes a file name and adds a numeric suffix to it if
 * there isn't one, or increments it otherwise.
 */
function rename(filename) {
	const ext = path.extname(filename);
	const base = path.basename(filename, ext);
	const bare = base.match(/^(.*?)(-\d+)?$/)[1]; // Strips out any -\d+ suffix
	const suffix = Number((base.match(/-(\d+)$/) || [])[1]) || 0; // Because NaN
	return `${bare}-${suffix+1}${ext}`;
}

/**
 * Save `data` as `filename` in `dirname`.
 */
async function saveFile (dirname, filename, data) {
	const fname = path.resolve(dirname, filename);
	if (fs.existsSync(fname)) {
		return await saveFile(dirname, rename(filename), data);
	} else {
		await fs.promises.writeFile(fname, data);
		return filename;
	}
}

/**
 * This method imitates the ASAQC endpoint
 * /vt/v1/api/upload-file-encoded
 *
 * If OUTPUT_DIR is defined, it tries to save the
 * received data as files in that directory, else
 * it discards the data but still produces a
 * plausible response.
 */
module.exports = async function (req, res, next) {

	try {
		const payload = req.body;
		const response = {id: uuid()};

		if (payload.fileName && payload.encodedData) {
			const data = Buffer.from(payload.encodedData, 'base64');

			console.log(`Received ${payload.fileName}, ${data.length} bytes`);

			if (req.app.locals.OUTPUT_DIR) {
				response.fileName = await saveFile(req.app.locals.OUTPUT_DIR, payload.fileName, data);
			} else {
				console.log("No disk output");
			}

			res.send(response);
		} else {
			res.status(400).send({message: "Bad syntax"});
		}
		next();
	} catch (err) {
		next(err);
	}

};
