
const FormData = require('form-data');
const fs = require("fs");
const tinifyUrl = 'https://tinify.duiba.com.cn/tinify';

function isPng(buffer) {
	if (!buffer || buffer.length < 8) {
		return false;
	}
	
	return buffer[0] === 0x89
		&& buffer[1] === 0x50
		&& buffer[2] === 0x4E
		&& buffer[3] === 0x47
		&& buffer[4] === 0x0D
		&& buffer[5] === 0x0A
		&& buffer[6] === 0x1A
		&& buffer[7] === 0x0A;
}

function isJpg(buffer) {
	if (!buffer || buffer.length < 3) {
		return false;
	}
	
	return buffer[0] === 255
		&& buffer[1] === 216
		&& buffer[2] === 255;
}

/**
 * 压缩图片
 * @param {Buffer|string} bufferOrFile
 * @return Promise<Buffer>
 */
async function tinyImage(bufferOrFile) {
	let buffer = bufferOrFile;
	if (typeof bufferOrFile === 'string') {
		buffer = fs.readFileSync(bufferOrFile);
	}
	return new Promise((resolve, reject) => {
		if (buffer && buffer.length > 0) {
			let extname = isPng(buffer) ? 'png' : 'jpeg';
			let form = new FormData();
			form.append('file', buffer, {
				filename: 'image.' + extname,
				contentType: 'image/' + extname,
			});
			form.submit(tinifyUrl, function (err, res) {
				if (err) {
					reject(err);
				}
				else {
					res.resume();
					let resBuffer = Buffer.alloc(0);
					res.on('data', (d) => {
						resBuffer = Buffer.concat([resBuffer, d], resBuffer.length + d.length);
					});
					res.on('end', () => {
						if (resBuffer.length > 256 || isPng(resBuffer) || isJpg(resBuffer)) {
							resolve(resBuffer);
						}
						else {
							let str = resBuffer.toString();
							let json;
							try {
								json = JSON.parse(str);
							}
							catch (e) {
								console.log(e);
							}
							reject(json.msg);
						}
					});
					res.on('abort', () => {
						reject('abort');
					});
				}
			});
		}
		else {
			reject('empty buffer');
		}
	});
}

module.exports = tinyImage;
