const fs = require('fs');
const path = require('path');
const assert = require('assert');
const glob = require('tiny-glob/sync.js');
const shell = require("shelljs");

const cli = path.resolve(__dirname, "../../cli/index.ts.js");

function normalize(str) {
	return str
		.replace(/^\s+$/gm, '')
		.replace(
			/\/\*(.*?)generated by Svelte v[.\d]+/,
			(_, path) => `/*${path.replace(/\\/g, '/')}generated by Svelte vx.y.z`
		)
		.trim();
}

const cwd = process.cwd();

describe('cli', () => {
	afterEach(() => {
		process.chdir(cwd);
	});

	fs.readdirSync('test/cli/samples').forEach(dir => {
		if (dir[0] === '.') return;

		// append .solo to test dir to only run that test
		const solo = /\.solo$/.test(dir);

		(solo ? it.only : it)(dir, done => {
			process.chdir(`${__dirname}/samples/${dir}`);

			const command = fs.readFileSync('command.sh', 'utf-8');

			shell.mkdir("-p", "actual");
			shell.rm("-rf", "actual/*");
			const { commandErr } = shell.exec(
				command.replace(/^svelte /, `node ${cli} `)
			);

			if (commandErr) {
				done(commandErr);
				return;
			}

			const actual = glob('**', { cwd: 'actual', filesOnly: true })
				.map(file => {
					return {
						file,
						contents: normalize(fs.readFileSync(`actual/${file}`, 'utf-8'))
					};
				});

			const expected = glob('**', { cwd: 'expected', filesOnly: true })
				.map(file => {
					return {
						file,
						contents: normalize(
							fs.readFileSync(`expected/${file}`, 'utf-8')
						)
					};
				});

			actual.forEach((a, i) => {
				const e = expected[i];

				assert.equal(a.file, e.file, 'File list mismatch');

				if (/\.map$/.test(a.file)) {
					assert.deepEqual(JSON.parse(a.contents), JSON.parse(e.contents));
				} else {
					assert.equal(a.contents, e.contents);
				}
			});

			done();
		});
	});
});