"use strict";

const Promise = require("bluebird");
const path = require("path");
const matchValue = require("match-value");
const defaultValue = require("default-value");
const thumbnailImage = require("../thumbnail-image");
const uploadFile = require("../upload-file");
const sendImageEvent = require("../send-image-event");
const universalImageMetadata = require("../universal-image-metadata");

const { validateArguments } = require("@validatem/core");
const required = require("@validatem/required");
const isInteger = require("@validatem/is-integer");
const isNonEmptyString = require("@validatem/is-non-empty-string");
const defaultTo = require("@validatem/default-to");
const isSession = require("@modular-matrix/is-session");
const isRoomID = require("../is-room-id");
const isPositive = require("../is-positive");

function thumbnailFilename(filename, mimetype) {
	let extension = matchValue(mimetype, {
		"image/png": "png",
		"image/jpeg": "jpeg"
	});

	if (filename != null) {
		let baseName = path.basename(filename, path.extname(filename));
		return `thumbnail-${baseName}.${extension}`;
	} else {
		return `thumbnail.${extension}`;
	}
}

module.exports = function sendImage(_session, _options) {
	let [ session, options ] = validateArguments(arguments, {
		session: [ required, isSession ],
		options: [ required, {
			roomID: [ required, isRoomID ],
			description: [ required, isNonEmptyString ],
			file: [ required ], // FIXME: Validate more strictly, something like isUploadable
			filename: [ isNonEmptyString ],
			thumbnail: [{
				maximumWidth: [ required, isInteger, isPositive ],
				maximumHeight: [ required, isInteger, isPositive ],
			}, defaultTo({ maximumWidth: 800, maximumHeight: 600 }) ]
		}]
	});

	return Promise.all([
		universalImageMetadata(options.file),
		uploadFile(session, {
			file: options.file,
			filename: options.filename
		})
	]).then(([ metadata, uploadResult ]) => {
		let fullSizeMXC = uploadResult.url;
		
		let desiredThumbnailMimetype = (metadata.mimetype === "image/jpeg")
			? "image/jpeg"
			: "image/png";

		return Promise.try(() => {
			return thumbnailImage({
				session: session,
				mxc: fullSizeMXC,
				maximumWidth: options.thumbnail.maximumWidth,
				maximumHeight: options.thumbnail.maximumHeight,
				file: options.file,
				mimetype: desiredThumbnailMimetype
			});
		}).then((thumbnail) => {
			let thumbnailFile = defaultValue(thumbnail.blob, thumbnail.buffer);
			let thumbnailFilesize = (thumbnail.buffer != null) ? thumbnail.buffer.length : thumbnail.blob.size;

			return Promise.try(() => {
				return uploadFile(session, {
					file: thumbnailFile,
					filename: thumbnailFilename(options.filename)
				});
			}).then((result) => {
				let thumbnailMXC = result.url;

				return sendImageEvent(session, {
					roomID: options.roomID,
					description: options.description,
					image: {
						url: fullSizeMXC,
						displayWidth: metadata.width,
						displayHeight: metadata.height,
						mimetype: metadata.mimetype,
						filesize: metadata.filesize
					},
					thumbnail: {
						url: thumbnailMXC,
						displayWidth: thumbnail.width,
						displayHeight: thumbnail.height,
						mimetype: defaultValue(thumbnail.mimetype, desiredThumbnailMimetype),
						filesize: thumbnailFilesize
					}
				});
			});
		});
	});
};
