"use strict";

const Promise = require("bluebird");
const matchValue = require("match-value");
const imageSize = require("image-size");
const fs = require("fs");
const getFilesize = require("../get-filesize");

const imageSizeAsync = Promise.promisify(imageSize);

function typeToMimetype(type) {
	return matchValue(type, {
		psd: "image/vnd.adobe.photoshop",
		bmp: "image/bmp",
		dds: "image/vnd-ms.dds",
		gif: "image/gif",
		tiff: "image/tiff",
		webp: "image/webp",
		icns: "image/icns",
		png: "image/png",
		jpg: "image/jpeg",
		cur: "image/x-icon",
		ico: "image/x-icon",
		j2c: "image/jp2",
		jp2: "image/jp2",
		ktx: "image/ktx",
		svg: "image/svg+xml"
	});
}

function analyzeBuffer(buffer) {
	return imageSize(buffer);
}

function analyzeBlob(blob) {
	return Promise.try(() => {
		return blob.arrayBuffer();
	}).then((buffer) => {
		return analyzeBuffer(buffer);
	});
}

function analyzeStream(stream) {
	return imageSizeAsync(stream.path);
}

function getImageData(image) {
	if (typeof Blob !== "undefined" && image instanceof Blob) {
		return analyzeBlob(image);
	} else if (Buffer.isBuffer(image)) {
		return analyzeBuffer(image);
	} else if (image._readableState != null && image.path != null) {
		return analyzeStream(image);
	} else {
		throw new Error(`Invalid file passed`); // FIXME: Validate
	}
}

module.exports = function getImageMetadata(image) {
	// image: buffer, arraybuffer, blob/file, fs stream
	return Promise.all([
		getFilesize(image),
		getImageData(image)
	]).then(([ filesize, { width, height, type } ]) => {
		return {
			width: width,
			height: height,
			filesize: filesize,
			mimetype: typeToMimetype(type)
		};
	});
};
