'use strict';

// Import

var _require = require('child_process'),
    spawn = _require.spawn;

var _require2 = require('assert-helpers'),
    equal = _require2.equal;

var _require3 = require('taskgroup'),
    Task = _require3.Task,
    TaskGroup = _require3.TaskGroup;

// Create a seperator


function sep(length, sep) {
	var str = '';
	for (var i = 0; i < length; ++i) {
		str += sep;
	}
	return str;
}

// Run a single test
function test(opts) {
	var expected = opts.expected,
	    script = opts.script,
	    reporter = opts.reporter;

	return new Task(function (complete) {
		// Prepare
		var expectedCleaned = expected.trim();

		// Test Reporter
		var output = '';
		var args = [script, '--joe-reporter=' + reporter, '--no-colors'];
		var str = args.join(' ');
		process.stdout.write(sep(str.length, '=') + '\n' + str + '\n\n');
		var runner = spawn('node', args, { env: process.env });
		runner.stdout.on('data', function (data) {
			output += data;
			process.stdout.write(data);
		});
		runner.stderr.on('data', function (data) {
			output += data;
			process.stderr.write(data);
		});
		runner.once('close', function () {
			output = output.replace(/[\n\s]+at .+/g, '').replace(/^\s|\s$/g, '');
			try {
				equal(output.trim(), expectedCleaned.trim());
			} catch (err) {
				return complete(err);
			}
			process.stdout.write('\n^^ the above was as expected ^^\n');
			return complete();
		});
	});
}

// Run multiple tests
function tests(opts, list) {
	return new TaskGroup({
		tasks: list.map(function (item) {
			Object.keys(opts).forEach(function (key) {
				item[key] = opts[key];
			});
			return test(item);
		})
	}).done(function (err) {
		if (err) {
			/* eslint no-console:0 */
			console.error(err.stack || err.message || err);
			process.exit(1);
		}
	}).run();
}

// Export
module.exports = { test: test, tests: tests };