const { spawn } = require("child_process");

// GM
async function callGM(params, stdin) {
	const out = [];
	const err = [];

	return await new Promise((resolve, reject) => {
		gm = spawn("gm", params);

		gm.stdout.on("data", (c) => out.push(c));
		gm.stderr.on("data", (c) => err.push(c));

		gm.on("close", (code) => {
			if (code !== 0) return reject(Buffer.concat(err).toString());

			resolve(Buffer.concat(out));
		});
		gm.stdin.end(stdin);
	});
}

class GMController {
	async cropImage(buffer, x, y, offsetX = 0, offsetY = 0) {
		return await callGM(
			["convert", "-", "-crop", `${x}x${y}+${offsetX}+${offsetY}`, "png:-"],
			buffer,
		);
	}

	// For change hash-sum by insignificant changes in pixel colors
	async repixelise(buffer) {
		const noiseAmount = Math.random() * 1; // 0..1%
		const brightness = (98 + Math.random() * 4).toFixed(2); // 98..102%

		return await callGM(
			["convert", "-", "-noise", ""+noiseAmount, "-modulate", brightness.toString(), "png:-"],
			buffer,
		);
	}
}

module.exports = new GMController();
