"use strict";

require("./helpers/warmup-webpack");

const path = require("path");
const expectNoDeprecations = require("./helpers/expectNoDeprecations");

expectNoDeprecations();

describe("WatchClose", () => {
	describe("multiple calls watcher", () => {
		const fixturePath = path.join(__dirname, "fixtures");
		const outputPath = path.join(__dirname, "js/WatchClose");
		const filePath = path.join(fixturePath, "a.js");

		/** @type {import("../").Compiler | null} */
		let compiler;
		/** @type {import("../").Watching} */
		let watcher;

		beforeEach(() => {
			const webpack = require("../");

			compiler = webpack({
				mode: "development",
				entry: filePath,
				output: {
					path: outputPath,
					filename: "bundle.js"
				}
			});
			watcher = /** @type {import("../").Watching} */ (
				/** @type {import("../").Compiler} */ (compiler).watch(
					{ poll: 300 },
					() => {}
				)
			);
		});

		afterEach(() => {
			/** @type {{ close: () => void }} */ (
				/** @type {unknown} */ (watcher)
			).close();
			compiler = null;
		});

		/**
		 * @param {import("../").Watching} watcher watcher
		 * @param {(err?: null | Error) => void} callback callback
		 * @returns {Promise<void>}
		 */
		function close(watcher, callback) {
			return new Promise((res) => {
				const onClose = () => {
					callback();
					res();
				};
				watcher.close(onClose);
			});
		}

		it("each callback should be called", async () => {
			let num = 0;

			await Promise.all([
				close(watcher, () => (num += 1)),
				close(watcher, () => (num += 10))
			]);
			await Promise.all([
				close(watcher, () => (num += 100)),
				close(watcher, () => (num += 1000))
			]);

			expect(num).toBe(1111);
		});
	});
});
