/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import {
	CancellationToken,
	DebugSession,
	Location,
	OutputChannel,
	Position,
	TestController,
	TestItem,
	TestMessage,
	TestRun,
	TestRunProfileKind,
	TestRunRequest,
	Uri,
	WorkspaceConfiguration
} from 'vscode';
import vscode = require('vscode');
import { outputChannel } from '../goStatus';
import { isModSupported } from '../goModules';
import { getGoConfig } from '../config';
import { getBenchmarkFunctions, getTestFlags, getTestFunctions, goTest, GoTestOutput } from '../testUtils';
import { GoTestResolver } from './resolve';
import { dispose, forEachAsync, GoTest, Workspace } from './utils';
import { GoTestProfiler, ProfilingOptions } from './profile';
import { debugTestAtCursor } from '../goTest';

let debugSessionID = 0;

type CollectedTest = { item: TestItem; explicitlyIncluded?: boolean };

interface RunConfig {
	goConfig: WorkspaceConfiguration;
	flags: string[];
	isMod: boolean;
	isBenchmark?: boolean;
	cancel: CancellationToken;

	run: TestRun;
	options: ProfilingOptions;
	pkg: TestItem;
	concat: boolean;
	record: Map<string, string[]>;
	functions: Record<string, TestItem>;
}

// TestRunOutput is a fake OutputChannel that forwards all test output to the test API
// console.
class TestRunOutput implements OutputChannel {
	readonly name: string;
	readonly lines: string[] = [];

	constructor(private run: TestRun) {
		this.name = `Test run at ${new Date()}`;
	}

	append(value: string) {
		this.run.appendOutput(value);
	}

	appendLine(value: string) {
		this.lines.push(value);
		this.run.appendOutput(value + '\r\n');
	}

	clear() {}
	// eslint-disable-next-line @typescript-eslint/no-unused-vars
	show(...args: unknown[]) {}
	hide() {}
	dispose() {}
}

export class GoTestRunner {
	constructor(
		private readonly workspace: Workspace,
		private readonly ctrl: TestController,
		private readonly resolver: GoTestResolver,
		private readonly profiler: GoTestProfiler
	) {
		ctrl.createRunProfile(
			'Go',
			TestRunProfileKind.Run,
			async (request, token) => {
				try {
					await this.run(request, token);
				} catch (error) {
					const m = 'Failed to execute tests';
					outputChannel.appendLine(`${m}: ${error}`);
					await vscode.window.showErrorMessage(m);
				}
			},
			true
		);

		ctrl.createRunProfile(
			'Go (Debug)',
			TestRunProfileKind.Debug,
			async (request, token) => {
				try {
					await this.debug(request, token);
				} catch (error) {
					const m = 'Failed to debug tests';
					outputChannel.appendLine(`${m}: ${error}`);
					await vscode.window.showErrorMessage(m);
				}
			},
			true
		);

		const pprof = ctrl.createRunProfile(
			'Go (Profile)',
			TestRunProfileKind.Run,
			async (request, token) => {
				try {
					await this.run(request, token, this.profiler.options);
				} catch (error) {
					const m = 'Failed to execute tests';
					outputChannel.appendLine(`${m}: ${error}`);
					await vscode.window.showErrorMessage(m);
				}
			},
			false
		);

		pprof.configureHandler = async () => {
			const state = await this.profiler.configure();
			if (!state) return;
			this.profiler.options = state;
		};
	}

	async debug(request: TestRunRequest, token?: CancellationToken) {
		if (!request.include) {
			await vscode.window.showErrorMessage('The Go test explorer does not support debugging multiple tests');
			return;
		}

		const collected = new Map<TestItem, CollectedTest[]>();
		const files = new Set<TestItem>();
		for (const item of request.include) {
			await this.collectTests(item, true, request.exclude || [], collected, files);
		}

		const tests = Array.from(collected.values()).reduce((a, b) => a.concat(b), []);
		if (tests.length > 1) {
			await vscode.window.showErrorMessage('The Go test explorer does not support debugging multiple tests');
			return;
		}

		const test = tests[0].item;
		const { kind, name } = GoTest.parseId(test.id);
		const doc = await vscode.workspace.openTextDocument(test.uri);
		await doc.save();

		const goConfig = getGoConfig(test.uri);
		const getFunctions = kind === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
		const testFunctions = await getFunctions(doc, token);

		// TODO Can we get output from the debug session, in order to check for
		// run/pass/fail events?

		const id = `debug #${debugSessionID++} ${name}`;
		const subs: vscode.Disposable[] = [];
		const sessionPromise = new Promise<DebugSession>((resolve) => {
			subs.push(
				vscode.debug.onDidStartDebugSession((s) => {
					if (s.configuration.sessionID === id) {
						resolve(s);
						subs.forEach((s) => s.dispose());
					}
				})
			);

			if (token) {
				subs.push(
					token.onCancellationRequested(() => {
						resolve(null);
						subs.forEach((s) => s.dispose());
					})
				);
			}
		});

		const run = this.ctrl.createTestRun(request, `Debug ${name}`);
		const started = await debugTestAtCursor(doc, name, testFunctions, goConfig, id);
		if (!started) {
			subs.forEach((s) => s.dispose());
			run.end();
			return;
		}

		const session = await sessionPromise;
		if (!session) {
			run.end();
			return;
		}

		token.onCancellationRequested(() => vscode.debug.stopDebugging(session));

		await new Promise<void>((resolve) => {
			const sub = vscode.debug.onDidTerminateDebugSession(didTerminateSession);

			token?.onCancellationRequested(() => {
				resolve();
				sub.dispose();
			});

			function didTerminateSession(s: DebugSession) {
				if (s.id !== session.id) return;
				resolve();
				sub.dispose();
			}
		});
		run.end();
	}

	// Execute tests - TestController.runTest callback
	async run(request: TestRunRequest, token?: CancellationToken, options: ProfilingOptions = {}): Promise<boolean> {
		const collected = new Map<TestItem, CollectedTest[]>();
		const files = new Set<TestItem>();
		if (request.include) {
			for (const item of request.include) {
				await this.collectTests(item, true, request.exclude || [], collected, files);
			}
		} else {
			const promises: Promise<unknown>[] = [];
			this.ctrl.items.forEach((item) => {
				const p = this.collectTests(item, true, request.exclude || [], collected, files);
				promises.push(p);
			});
			await Promise.all(promises);
		}

		// Save all documents that contain a test we're about to run, to ensure `go
		// test` has the latest changes
		const fileUris = new Set(Array.from(files).map((x) => x.uri));
		await Promise.all(this.workspace.textDocuments.filter((x) => fileUris.has(x.uri)).map((x) => x.save()));

		let hasBench = false,
			hasNonBench = false;
		for (const items of collected.values()) {
			for (const { item } of items) {
				const { kind } = GoTest.parseId(item.id);
				if (kind === 'benchmark') hasBench = true;
				else hasNonBench = true;
			}
		}

		function isInMod(item: TestItem): boolean {
			const { kind } = GoTest.parseId(item.id);
			if (kind === 'module') return true;
			if (!item.parent) return false;
			return isInMod(item.parent);
		}

		const run = this.ctrl.createTestRun(request);
		const windowGoConfig = getGoConfig();
		if (windowGoConfig.get<boolean>('testExplorer.showOutput')) {
			await vscode.commands.executeCommand('testing.showMostRecentOutput');
		}

		let success = true;
		const subItems: string[] = [];
		for (const [pkg, items] of collected.entries()) {
			const isMod = isInMod(pkg) || (await isModSupported(pkg.uri, true));
			const goConfig = getGoConfig(pkg.uri);
			const flags = getTestFlags(goConfig);
			const includeBench = getGoConfig(pkg.uri).get('testExplorer.alwaysRunBenchmarks');

			// If any of the tests are test suite methods, add all test functions that call `suite.Run`
			const hasTestMethod = items.some(({ item }) => this.resolver.isTestMethod.has(item));
			if (hasTestMethod) {
				const add: TestItem[] = [];
				pkg.children.forEach((file) => {
					file.children.forEach((test) => {
						if (!this.resolver.isTestSuiteFunc.has(test)) return;
						if (items.some(({ item }) => item === test)) return;
						add.push(test);
					});
				});
				items.push(...add.map((item) => ({ item })));
			}

			// Separate tests and benchmarks and mark them as queued for execution.
			// Clear any sub tests/benchmarks generated by a previous run.
			const tests: Record<string, TestItem> = {};
			const benchmarks: Record<string, TestItem> = {};
			for (const { item, explicitlyIncluded } of items) {
				const { kind, name } = GoTest.parseId(item.id);
				if (/[/#]/.test(name)) subItems.push(name);

				// When the user clicks the run button on a package, they expect all
				// of the tests within that package to run - they probably don't
				// want to run the benchmarks. So if a benchmark is not explicitly
				// selected, don't run benchmarks. But the user may disagree, so
				// behavior can be changed with `go.testExplorerRunBenchmarks`.
				// However, if the user clicks the run button on a file or package
				// that contains benchmarks and nothing else, they likely expect
				// those benchmarks to run.
				if (kind === 'benchmark' && !explicitlyIncluded && !includeBench && !(hasBench && !hasNonBench)) {
					continue;
				}

				item.error = null;
				run.enqueued(item);

				// Remove subtests created dynamically from test output
				item.children.forEach((child) => {
					if (this.resolver.isDynamicSubtest.has(child)) {
						dispose(this.resolver, child);
					}
				});

				if (kind === 'benchmark') {
					benchmarks[name] = item;
				} else {
					tests[name] = item;
				}
			}

			const record = new Map<string, string[]>();
			const concat = goConfig.get<boolean>('testExplorer.concatenateMessages');

			// https://github.com/golang/go/issues/39904
			if (subItems.length > 0 && Object.keys(tests).length + Object.keys(benchmarks).length > 1) {
				outputChannel.appendLine(
					`The following tests in ${pkg.uri} failed to run, as go test will only run a sub-test or sub-benchmark if it is by itself:`
				);
				Object.keys(tests)
					.concat(Object.keys(benchmarks))
					.forEach((x) => outputChannel.appendLine(x));
				outputChannel.show();
				vscode.window.showErrorMessage(
					`Cannot run the selected tests in package ${pkg.label} - see the Go output panel for details`
				);
				continue;
			}

			const config = {
				flags,
				isMod,
				goConfig,
				cancel: token,

				run,
				options,
				pkg,
				record,
				concat
			};

			// Run tests
			if (!options.kind) {
				const r = await this.runGoTest({ ...config, functions: tests });
				if (!r) success = false;
			} else {
				for (const name in tests) {
					const r = await this.runGoTest({ ...config, functions: { [name]: tests[name] } });
					if (!r) success = false;
				}
			}

			// Run benchmarks
			if (!options.kind) {
				const r = await this.runGoTest({ ...config, isBenchmark: true, functions: benchmarks });
				if (!r) success = false;
			} else {
				for (const name in benchmarks) {
					const r = await this.runGoTest({
						...config,
						isBenchmark: true,
						functions: { [name]: benchmarks[name] }
					});
					if (!r) success = false;
				}
			}

			if (token?.isCancellationRequested) {
				break;
			}
		}

		run.end();

		this.profiler.postRun();

		return success;
	}

	// Recursively find all tests, benchmarks, and examples within a
	// module/package/etc, minus exclusions. Map tests to the package they are
	// defined in, and track files.
	async collectTests(
		item: TestItem,
		explicitlyIncluded: boolean,
		excluded: TestItem[],
		functions: Map<TestItem, CollectedTest[]>,
		files: Set<TestItem>
	) {
		for (let i = item; i.parent; i = i.parent) {
			if (excluded.indexOf(i) >= 0) {
				return;
			}
		}

		const { name } = GoTest.parseId(item.id);
		if (!name) {
			if (item.children.size === 0) {
				await this.resolver.resolve(item);
			}

			await forEachAsync(item.children, (child) => {
				return this.collectTests(child, false, excluded, functions, files);
			});
			return;
		}

		function getFile(item: TestItem): TestItem {
			const { kind } = GoTest.parseId(item.id);
			if (kind === 'file') return item;
			return getFile(item.parent);
		}

		const file = getFile(item);
		files.add(file);

		const pkg = file.parent;
		if (functions.has(pkg)) {
			functions.get(pkg).push({ item, explicitlyIncluded });
		} else {
			functions.set(pkg, [{ item, explicitlyIncluded }]);
		}
		return;
	}

	private async runGoTest(config: RunConfig): Promise<boolean> {
		const { run, options, pkg, functions, record, concat, ...rest } = config;
		if (Object.keys(functions).length === 0) return true;

		if (options.kind) {
			if (Object.keys(functions).length > 1) {
				throw new Error('Profiling more than one test at once is unsupported');
			}
			rest.flags.push(...this.profiler.preRun(options, Object.values(functions)[0]));
		}

		const complete = new Set<TestItem>();
		const outputChannel = new TestRunOutput(run);

		const success = await goTest({
			...rest,
			outputChannel,
			dir: pkg.uri.fsPath,
			functions: Object.keys(functions),
			goTestOutputConsumer: rest.isBenchmark
				? (e) => this.consumeGoBenchmarkEvent(run, functions, complete, e)
				: (e) => this.consumeGoTestEvent(run, functions, record, complete, concat, e)
		});
		if (success) {
			if (rest.isBenchmark) {
				this.markComplete(functions, complete, (x) => run.passed(x));
			}
			return true;
		}

		if (this.isBuildFailure(outputChannel.lines)) {
			this.markComplete(functions, new Set(), (item) => {
				run.errored(item, { message: 'Compilation failed' });
				item.error = 'Compilation failed';
			});
		} else {
			this.markComplete(functions, complete, (x) => run.skipped(x));
		}
		return false;
	}

	// Resolve a test name to a test item. If the test name is TestXxx/Foo, Foo is
	// created as a child of TestXxx.
	resolveTestName(tests: Record<string, TestItem>, name: string): TestItem | undefined {
		if (!name) {
			return;
		}

		// Heuristically determines whether a test is a subtest by checking the existence of "/".
		// BUG: go test does not escape "/" included in the name passed to t.Run, so that
		// can result in confusing presentation.
		const re = /\/+/;

		const resolve = (parent?: TestItem, start = 0, length = 0): TestItem | undefined => {
			const pos = start + length;
			const m = name.substring(pos).match(re);
			if (!m) {
				if (!parent) return tests[name];
				return this.resolver.getOrCreateSubTest(parent, name.substring(pos), name, true);
			}

			const subName = name.substring(0, pos + m.index);
			const test = parent
				? this.resolver.getOrCreateSubTest(parent, name.substring(pos, pos + m.index), subName, true)
				: tests[subName];
			return resolve(test, pos + m.index, m[0].length);
		};

		return resolve();
	}

	// Process benchmark events (see test_events.md)
	consumeGoBenchmarkEvent(
		run: TestRun,
		benchmarks: Record<string, TestItem>,
		complete: Set<TestItem>,
		e: GoTestOutput
	) {
		if (e.Test) {
			// Find (or create) the (sub)benchmark
			const test = this.resolveTestName(benchmarks, e.Test);
			if (!test) {
				return;
			}

			switch (e.Action) {
				case 'fail': // Failed
					run.failed(test, { message: 'Failed' });
					complete.add(test);
					break;

				case 'skip': // Skipped
					run.skipped(test);
					complete.add(test);
					break;
			}

			return;
		}

		// Ignore anything that's not an output event
		if (!e.Output) {
			return;
		}

		// On start:    "BenchmarkFooBar"
		// On complete: "BenchmarkFooBar-4    123456    123.4 ns/op    123 B/op    12 allocs/op"

		// Extract the benchmark name and status
		const m = e.Output.match(/^(?<name>Benchmark[/\w]+)(?:-(?<procs>\d+)\s+(?<result>.*))?(?:$|\n)/);
		if (!m) {
			// If the output doesn't start with `BenchmarkFooBar`, ignore it
			return;
		}

		// Find (or create) the (sub)benchmark
		const test = this.resolveTestName(benchmarks, m.groups.name);
		if (!test) {
			return;
		}

		// If output includes benchmark results, the benchmark passed. If output
		// only includes the benchmark name, the benchmark is running.
		if (m.groups.result) {
			run.passed(test);
			complete.add(test);
			vscode.commands.executeCommand('testing.showMostRecentOutput');
		} else {
			run.started(test);
		}
	}

	// Pass any incomplete benchmarks (see test_events.md)
	markComplete(items: Record<string, TestItem>, complete: Set<TestItem>, fn: (item: TestItem) => void) {
		function mark(item: TestItem) {
			if (!complete.has(item)) {
				fn(item);
			}
			item.children.forEach((child) => mark(child));
		}

		for (const name in items) {
			mark(items[name]);
		}
	}

	// Process test events (see test_events.md)
	consumeGoTestEvent(
		run: TestRun,
		tests: Record<string, TestItem>,
		record: Map<string, string[]>,
		complete: Set<TestItem>,
		concat: boolean,
		e: GoTestOutput
	) {
		const test = this.resolveTestName(tests, e.Test);
		if (!test) {
			return;
		}

		switch (e.Action) {
			case 'cont':
			case 'pause':
				// ignore
				break;

			case 'run':
				run.started(test);
				break;

			case 'pass':
				// TODO(firelizzard18): add messages on pass, once that capability
				// is added.
				complete.add(test);
				run.passed(test, e.Elapsed * 1000);
				break;

			case 'fail': {
				complete.add(test);
				const messages = this.parseOutput(test, record.get(test.id) || []);

				if (!concat) {
					run.failed(test, messages, e.Elapsed * 1000);
					break;
				}

				const merged = new Map<string, TestMessage>();
				for (const { message, location } of messages) {
					const loc = `${location.uri}:${location.range.start.line}`;
					if (merged.has(loc)) {
						merged.get(loc).message += '\n' + message;
					} else {
						merged.set(loc, { message, location });
					}
				}

				run.failed(test, Array.from(merged.values()), e.Elapsed * 1000);
				break;
			}

			case 'skip':
				complete.add(test);
				run.skipped(test);
				break;

			case 'output':
				if (/^(=== RUN|\s*--- (FAIL|PASS): )/.test(e.Output)) {
					break;
				}

				if (record.has(test.id)) record.get(test.id).push(e.Output);
				else record.set(test.id, [e.Output]);
				break;
		}
	}

	parseOutput(test: TestItem, output: string[]): TestMessage[] {
		const messages: TestMessage[] = [];

		const { kind } = GoTest.parseId(test.id);
		const gotI = output.indexOf('got:\n');
		const wantI = output.indexOf('want:\n');
		if (kind === 'example' && gotI >= 0 && wantI >= 0) {
			const got = output.slice(gotI + 1, wantI).join('');
			const want = output.slice(wantI + 1).join('');
			const message = TestMessage.diff('Output does not match', want, got);
			message.location = new Location(test.uri, test.range.start);
			messages.push(message);
			output = output.slice(0, gotI);
		}

		let current: Location;
		const dir = Uri.joinPath(test.uri, '..');
		for (const line of output) {
			const m = line.match(/^\s*(?<file>.*\.go):(?<line>\d+): ?(?<message>.*\n)$/);
			if (m) {
				const file = Uri.joinPath(dir, m.groups.file);
				const ln = Number(m.groups.line) - 1; // VSCode uses 0-based line numbering (internally)
				current = new Location(file, new Position(ln, 0));
				messages.push({ message: m.groups.message, location: current });
			} else if (current) {
				messages.push({ message: line, location: current });
			}
		}

		return messages;
	}

	isBuildFailure(output: string[]): boolean {
		const rePkg = /^# (?<pkg>[\w/.-]+)(?: \[(?<test>[\w/.-]+).test\])?/;

		// TODO(firelizzard18): Add more sophisticated check for build failures?
		return output.some((x) => rePkg.test(x));
	}
}
