/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-useless-escape */
/* eslint-disable no-async-promise-executor */
/* eslint-disable no-prototype-builtins */
/* eslint-disable @typescript-eslint/no-explicit-any */
/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import cp = require('child_process');
import path = require('path');
import util = require('util');
import vscode = require('vscode');

import { applyCodeCoverageToAllEditors } from './goCover';
import { toolExecutionEnvironment } from './goEnv';
import { getCurrentPackage } from './goModules';
import { GoDocumentSymbolProvider } from './goDocumentSymbols';
import { getNonVendorPackages } from './goPackages';
import { getBinPath, getCurrentGoPath, getTempFilePath, LineBuffer, resolvePath } from './util';
import { parseEnvFile } from './utils/envUtils';
import { envPath, expandFilePathInOutput, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH } from './utils/pathUtils';
import { killProcessTree } from './utils/processUtils';
import { GoExtensionContext } from './context';

const testOutputChannel = vscode.window.createOutputChannel('Go Tests');
const STATUS_BAR_ITEM_NAME = 'Go Test Cancel';
const statusBarItem = vscode.window.createStatusBarItem(STATUS_BAR_ITEM_NAME, vscode.StatusBarAlignment.Left);
statusBarItem.name = STATUS_BAR_ITEM_NAME;
statusBarItem.command = 'go.test.cancel';
statusBarItem.text = '$(x) Cancel Running Tests';

/**
 *  testProcesses holds a list of currently running test processes.
 */
const runningTestProcesses: cp.ChildProcess[] = [];

// https://github.com/golang/go/blob/117b1c84d3678a586c168a5f7f2f0a750c27f0c2/src/cmd/go/internal/load/test.go#L487
// uses !unicode.isLower to find test/example/benchmark functions.
// There could be slight difference between \P{Ll} (not lowercase letter)
// & go unicode package's uppercase detection. But hopefully
// these will be replaced by gopls's codelens computation soon.
const testFuncRegex = /^Test$|^Test\P{Ll}.*|^Example$|^Example\P{Ll}.*/u;
const testMethodRegex = /^\(([^)]+)\)\.(Test|Test\P{Ll}.*)$/u;
const benchmarkRegex = /^Benchmark$|^Benchmark\P{Ll}.*/u;
const fuzzFuncRegx = /^Fuzz$|^Fuzz\P{Ll}.*/u;
/**
 * Input to goTest.
 */
export interface TestConfig {
	/**
	 * The working directory for `go test`.
	 */
	dir: string;
	/**
	 * Configuration for the Go extension
	 */
	goConfig: vscode.WorkspaceConfiguration;
	/**
	 * Test flags to override the testFlags and buildFlags from goConfig.
	 */
	flags: string[];
	/**
	 * Specific function names to test.
	 */
	functions?: string[];
	/**
	 * Test was not requested explicitly. The output should not appear in the UI.
	 */
	background?: boolean;
	/**
	 * Run all tests from all sub directories under `dir`
	 */
	includeSubDirectories?: boolean;
	/**
	 * Whether this is a benchmark.
	 */
	isBenchmark?: boolean;
	/**
	 * Whether the tests are being run in a project that uses Go modules
	 */
	isMod?: boolean;
	/**
	 * Whether code coverage should be generated and applied.
	 */
	applyCodeCoverage?: boolean;
	/**
	 * Output channel for test output.
	 */
	outputChannel?: vscode.OutputChannel;
	/**
	 * Can be used to terminate the test process.
	 */
	cancel?: vscode.CancellationToken;
	/**
	 * Output channel for JSON test output.
	 */
	goTestOutputConsumer?: (_: GoTestOutput) => void;
}

export function getTestEnvVars(config: vscode.WorkspaceConfiguration): any {
	const envVars = toolExecutionEnvironment();
	const testEnvConfig = config['testEnvVars'] || {};

	let fileEnv: { [key: string]: any } = {};
	let testEnvFile = config['testEnvFile'];
	if (testEnvFile) {
		testEnvFile = resolvePath(testEnvFile);
		try {
			fileEnv = parseEnvFile(testEnvFile);
		} catch (e) {
			console.log(e);
		}
	}

	Object.keys(fileEnv).forEach(
		(key) => (envVars[key] = typeof fileEnv[key] === 'string' ? resolvePath(fileEnv[key]) : fileEnv[key])
	);
	Object.keys(testEnvConfig).forEach(
		(key) =>
			(envVars[key] =
				typeof testEnvConfig[key] === 'string' ? resolvePath(testEnvConfig[key]) : testEnvConfig[key])
	);

	return envVars;
}

export function getTestFlags(goConfig: vscode.WorkspaceConfiguration, args?: any): string[] {
	let testFlags: string[] = goConfig['testFlags'] || goConfig['buildFlags'] || [];
	testFlags = testFlags.map((x) => resolvePath(x)); // Use copy of the flags, dont pass the actual object from config
	return args && args.hasOwnProperty('flags') && Array.isArray(args['flags']) ? args['flags'] : testFlags;
}

export function getTestTags(goConfig: vscode.WorkspaceConfiguration): string {
	return goConfig['testTags'] !== null ? goConfig['testTags'] : goConfig['buildTags'];
}

/**
 * Returns all Go unit test functions in the given source file.
 *
 * @param the URI of a Go source file.
 * @return test function symbols for the source file.
 */
export async function getTestFunctions(
	goCtx: GoExtensionContext,
	doc: vscode.TextDocument,
	token?: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[] | undefined> {
	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx, true);
	const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
	if (!symbols || symbols.length === 0) {
		return;
	}
	const symbol = symbols[0];
	if (!symbol) {
		return;
	}
	const children = symbol.children;
	const testify = importsTestify(symbols);
	return children.filter(
		(sym) =>
			(sym.kind === vscode.SymbolKind.Function || sym.kind === vscode.SymbolKind.Method) &&
			(testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name) || (testify && testMethodRegex.test(sym.name)))
	);
}

/**
 * Extracts test method name of a suite test function.
 * For example a symbol with name "(*testSuite).TestMethod" will return "TestMethod".
 *
 * @param symbolName Symbol Name to extract method name from.
 */
export function extractInstanceTestName(symbolName: string): string {
	const match = symbolName.match(testMethodRegex);
	if (!match || match.length !== 3) {
		return '';
	}
	return match[2];
}

/**
 * Gets the appropriate debug arguments for a debug session on a test function.
 * @param document  The document containing the tests
 * @param testFunctionName The test function to get the debug args
 * @param testFunctions The test functions found in the document
 */
export function getTestFunctionDebugArgs(
	document: vscode.TextDocument,
	testFunctionName: string,
	testFunctions: vscode.DocumentSymbol[]
): string[] {
	if (benchmarkRegex.test(testFunctionName)) {
		return ['-test.bench', '^' + testFunctionName + '$', '-test.run', 'a^'];
	}
	const instanceMethod = extractInstanceTestName(testFunctionName);
	if (instanceMethod) {
		const testFns = findAllTestSuiteRuns(document, testFunctions);
		const testSuiteRuns = ['-test.run', `^${testFns.map((t) => t.name).join('|')}$`];
		const testSuiteTests = ['-testify.m', `^${instanceMethod}$`];
		return [...testSuiteRuns, ...testSuiteTests];
	} else {
		return ['-test.run', `^${testFunctionName}$`];
	}
}
/**
 * Finds test methods containing "suite.Run()" call.
 *
 * @param doc Editor document
 * @param allTests All test functions
 */
export function findAllTestSuiteRuns(
	doc: vscode.TextDocument,
	allTests: vscode.DocumentSymbol[]
): vscode.DocumentSymbol[] {
	// get non-instance test functions
	const testFunctions = allTests?.filter((t) => !testMethodRegex.test(t.name));
	// filter further to ones containing suite.Run()
	return testFunctions?.filter((t) => doc.getText(t.range).includes('suite.Run(')) ?? [];
}

/**
 * Returns all Benchmark functions in the given source file.
 *
 * @param the URI of a Go source file.
 * @return benchmark function symbols for the source file.
 */
export async function getBenchmarkFunctions(
	goCtx: GoExtensionContext,
	doc: vscode.TextDocument,
	token?: vscode.CancellationToken
): Promise<vscode.DocumentSymbol[] | undefined> {
	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
	const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
	if (!symbols || symbols.length === 0) {
		return;
	}
	const symbol = symbols[0];
	if (!symbol) {
		return;
	}
	const children = symbol.children;
	return children.filter((sym) => sym.kind === vscode.SymbolKind.Function && benchmarkRegex.test(sym.name));
}

/**
 * go test -json output format.
 * which is a subset of https://golang.org/cmd/test2json/#hdr-Output_Format
 * and includes only the fields that we are using.
 */
export interface GoTestOutput {
	Action: string;
	Output?: string;
	Package?: string;
	Test?: string;
	Elapsed?: number; // seconds
}

/**
 * Runs go test and presents the output in the 'Go' channel.
 *
 * @param goConfig Configuration for the Go extension.
 */
export async function goTest(testconfig: TestConfig): Promise<boolean> {
	let outputChannel = testOutputChannel;
	if (testconfig.outputChannel) {
		outputChannel = testconfig.outputChannel;
	}

	const goRuntimePath = getBinPath('go');
	if (!goRuntimePath) {
		vscode.window.showErrorMessage(
			`Failed to run "go test" as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
		);
		return Promise.resolve(false);
	}

	// We do not want to clear it if tests are already running, as that could
	// lose valuable output.
	if (runningTestProcesses.length < 1) {
		outputChannel.clear();
	}

	if (testconfig.goConfig['disableConcurrentTests']) {
		await cancelRunningTests();
	}

	if (!testconfig.background) {
		outputChannel.show(true);
	}

	const testType: string = testconfig.isBenchmark ? 'Benchmarks' : 'Tests';

	// compute test target package
	const { targets, pkgMap, currentGoWorkspace } = await getTestTargetPackages(testconfig, outputChannel);

	// generate full test args.
	const { args, outArgs, tmpCoverPath, addJSONFlag } = computeTestCommand(testconfig, targets);

	outputChannel.appendLine(['Running tool:', goRuntimePath, ...outArgs].join(' '));
	outputChannel.appendLine('');

	let testResult = false;
	try {
		testResult = await new Promise<boolean>(async (resolve, reject) => {
			const testEnvVars = getTestEnvVars(testconfig.goConfig);
			const tp = cp.spawn(goRuntimePath, args, { env: testEnvVars, cwd: testconfig.dir });
			const outBuf = new LineBuffer();
			const errBuf = new LineBuffer();

			testconfig.cancel?.onCancellationRequested(() => killProcessTree(tp));

			const testResultLines: string[] = [];
			const processTestResultLine = addJSONFlag
				? processTestResultLineInJSONMode(
						pkgMap,
						currentGoWorkspace,
						outputChannel,
						testconfig.goTestOutputConsumer
				  )
				: processTestResultLineInStandardMode(pkgMap, currentGoWorkspace, testResultLines, outputChannel);

			outBuf.onLine((line) => processTestResultLine(line));
			outBuf.onDone((last) => {
				if (last) {
					processTestResultLine(last);
				}

				// If there are any remaining test result lines, emit them to the output channel.
				if (testResultLines.length > 0) {
					testResultLines.forEach((line) => outputChannel.appendLine(line));
				}
			});

			// go test emits build errors on stderr, which contain paths relative to the cwd
			errBuf.onLine((line) => outputChannel.appendLine(expandFilePathInOutput(line, testconfig.dir)));
			errBuf.onDone((last) => last && outputChannel.appendLine(expandFilePathInOutput(last, testconfig.dir)));

			tp.stdout.on('data', (chunk) => outBuf.append(chunk.toString()));
			tp.stderr.on('data', (chunk) => errBuf.append(chunk.toString()));

			statusBarItem.show();

			tp.on('close', (code, signal) => {
				outBuf.done();
				errBuf.done();

				const index = runningTestProcesses.indexOf(tp, 0);
				if (index > -1) {
					runningTestProcesses.splice(index, 1);
				}

				if (!runningTestProcesses.length) {
					statusBarItem.hide();
				}

				resolve(code === 0);
			});

			runningTestProcesses.push(tp);
		});
	} catch (err) {
		outputChannel.appendLine(`Error: ${testType} failed.`);
		if (err instanceof Error) {
			outputChannel.appendLine((err as Error).message);
		}
	}
	if (tmpCoverPath) {
		await applyCodeCoverageToAllEditors(tmpCoverPath, testconfig.dir);
	}
	return testResult;
}

async function getTestTargetPackages(testconfig: TestConfig, outputChannel: vscode.OutputChannel) {
	const targets = testconfig.includeSubDirectories ? ['./...'] : [];
	let currentGoWorkspace = '';
	let getCurrentPackagePromise: Promise<string> | undefined;
	let pkgMapPromise: Promise<Map<string, string> | void>;
	if (testconfig.isMod) {
		getCurrentPackagePromise = getCurrentPackage(testconfig.dir);
		// We need the mapping to get absolute paths for the files in the test output.
		pkgMapPromise = getNonVendorPackages(testconfig.dir, !!testconfig.includeSubDirectories);
	} else {
		// GOPATH mode
		currentGoWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), testconfig.dir);
		getCurrentPackagePromise = Promise.resolve(
			currentGoWorkspace ? testconfig.dir.substr(currentGoWorkspace.length + 1) : ''
		);
		// We dont need mapping, as we can derive the absolute paths from package path
		pkgMapPromise = Promise.resolve();
	}

	let pkgMap = new Map<string, string>();
	// run go list to populate pkgMap and currentPackage necessary to adjust the test output later.
	try {
		const [pkgMap0, currentPackage] = await Promise.all([pkgMapPromise, getCurrentPackagePromise]);
		if (pkgMap0) {
			pkgMap = pkgMap0;
		}
		// Use the package name to be in the args to enable running tests in symlinked directories
		// TODO(hyangah): check why modules mode didn't set currentPackage.
		if (!testconfig.includeSubDirectories && currentPackage) {
			targets.splice(0, 0, currentPackage);
		}
	} catch (err) {
		outputChannel.appendLine(`warning: failed to compute package mapping... ${err}`);
	}
	return { targets, pkgMap, currentGoWorkspace };
}

// computeTestCommand returns the test command argument list and extra info necessary
// to post process the test results.
// Exported for testing.
export function computeTestCommand(
	testconfig: TestConfig,
	targets: string[]
): {
	args: Array<string>; // test command args.
	outArgs: Array<string>; // compact test command args to show to user.
	tmpCoverPath?: string; // coverage file path if coverage info is necessary.
	addJSONFlag: boolean | undefined; // true if we add extra -json flag for stream processing.
} {
	const args: Array<string> = ['test'];
	// user-specified flags
	const argsFlagIdx = testconfig.flags?.indexOf('-args') ?? -1;
	const userFlags = argsFlagIdx < 0 ? testconfig.flags : testconfig.flags.slice(0, argsFlagIdx);
	const userArgsFlags = argsFlagIdx < 0 ? [] : testconfig.flags.slice(argsFlagIdx);

	// flags to limit test time
	if (testconfig.isBenchmark) {
		args.push('-benchmem', '-run=^$');
	} else {
		args.push('-timeout', testconfig.goConfig['testTimeout']);
	}

	// tags flags only if user didn't set -tags yet.
	const testTags: string = getTestTags(testconfig.goConfig);
	if (testTags && userFlags.indexOf('-tags') === -1) {
		args.push('-tags', testTags);
	}

	// coverage flags
	let tmpCoverPath: string | undefined;
	if (testconfig.applyCodeCoverage) {
		tmpCoverPath = getTempFilePath('go-code-cover');
		args.push('-coverprofile=' + tmpCoverPath);
		const coverMode = testconfig.goConfig['coverMode'];
		switch (coverMode) {
			case 'default':
				break;
			case 'set':
			case 'count':
			case 'atomic':
				args.push('-covermode', coverMode);
				break;
			default:
				vscode.window.showWarningMessage(
					`go.coverMode=${coverMode} is illegal. Use 'set', 'count', 'atomic', or 'default'.`
				);
		}
	}

	// all other test run/benchmark flags
	args.push(...targetArgs(testconfig));

	const outArgs = args.slice(0); // command to show

	// if user set -v, set -json to emulate streaming test output
	const addJSONFlag = (userFlags.includes('-v') || testconfig.goTestOutputConsumer) && !userFlags.includes('-json');
	if (addJSONFlag) {
		args.push('-json'); // this is not shown to the user.
	}

	if (targets.length > 4) {
		outArgs.push('<long arguments omitted>');
	} else {
		outArgs.push(...targets);
	}
	args.push(...targets);

	// ensure that user provided flags are appended last (allow use of -args ...)
	// ignore user provided -run flag if we are already using it
	if (args.indexOf('-run') > -1) {
		removeRunFlag(userFlags);
	}

	args.push(...userFlags);
	outArgs.push(...userFlags);

	args.push(...userArgsFlags);
	outArgs.push(...userArgsFlags);

	return {
		args,
		outArgs,
		tmpCoverPath,
		addJSONFlag
	};
}

function processTestResultLineInJSONMode(
	pkgMap: Map<string, string>,
	currentGoWorkspace: string,
	outputChannel: vscode.OutputChannel,
	goTestOutputConsumer?: (_: GoTestOutput) => void
) {
	return (line: string) => {
		try {
			const m = <GoTestOutput>JSON.parse(line);
			if (goTestOutputConsumer) {
				goTestOutputConsumer(m);
			}
			if (m.Action !== 'output' || !m.Output) {
				return;
			}
			const out = m.Output;
			const pkg = m.Package;
			if (pkg && (pkgMap.has(pkg) || currentGoWorkspace)) {
				const pkgNameArr = pkg.split('/');
				const baseDir = pkgMap.get(pkg) || path.join(currentGoWorkspace, ...pkgNameArr);
				// go test emits test results on stdout, which contain file names relative to the package under test
				outputChannel.appendLine(expandFilePathInOutput(out, baseDir).trimRight());
			} else {
				outputChannel.appendLine(out.trimRight());
			}
		} catch (e) {
			// TODO: disable this log if it becomes too spammy.
			console.log(`failed to parse JSON: ${e}: ${line}`);
			// Build failures or other messages come in non-JSON format. So, output as they are.
			outputChannel.appendLine(line);
		}
	};
}

function processTestResultLineInStandardMode(
	pkgMap: Map<string, string>,
	currentGoWorkspace: string,
	testResultLines: string[],
	outputChannel: vscode.OutputChannel
) {
	// 1=ok/FAIL/?, 2=package, 3=time/(cached)/[no test files]
	const packageResultLineRE = /^(ok|FAIL|\?)\s+(\S+)\s+([0-9\.]+s|\(cached\)|\[no test files\])/;
	const lineWithErrorRE = /^\s+(\S+\.go):(\d+):/;

	return (line: string) => {
		testResultLines.push(line);
		const result = line.match(packageResultLineRE);
		if (result && (pkgMap.has(result[2]) || currentGoWorkspace)) {
			const hasTestFailed = line.startsWith('FAIL');
			const packageNameArr = result[2].split('/');
			const baseDir = pkgMap.get(result[2]) || path.join(currentGoWorkspace, ...packageNameArr);
			testResultLines.forEach((testResultLine) => {
				if (hasTestFailed && lineWithErrorRE.test(testResultLine)) {
					outputChannel.appendLine(expandFilePathInOutput(testResultLine, baseDir));
				} else {
					outputChannel.appendLine(testResultLine);
				}
			});
			testResultLines.splice(0);
		}
	};
}

/**
 * Reveals the output channel in the UI.
 */
export function showTestOutput() {
	testOutputChannel.show(true);
}

/**
 * Iterates the list of currently running test processes and kills them all.
 */
export function cancelRunningTests(): Thenable<boolean> {
	return new Promise<boolean>((resolve, reject) => {
		runningTestProcesses.forEach((tp) => {
			killProcessTree(tp);
		});
		// All processes are now dead. Empty the array to prepare for the next run.
		runningTestProcesses.splice(0, runningTestProcesses.length);
		statusBarItem.hide();
		resolve(true);
	});
}

/**
 * Get the test target arguments.
 *
 * @param testconfig Configuration for the Go extension.
 */
function targetArgs(testconfig: TestConfig): Array<string> {
	let params: string[] = [];

	if (testconfig.functions) {
		if (testconfig.isBenchmark) {
			if (testconfig.functions.length === 1) {
				params = ['-bench', util.format('^%s$', testconfig.functions[0])];
			} else {
				params = ['-bench', util.format('^(%s)$', testconfig.functions.join('|'))];
			}
		} else {
			let testFunctions = testconfig.functions;
			let testifyMethods = testFunctions.filter((fn) => testMethodRegex.test(fn));
			if (testifyMethods.length > 0) {
				// filter out testify methods
				testFunctions = testFunctions.filter((fn) => !testMethodRegex.test(fn));
				testifyMethods = testifyMethods.map(extractInstanceTestName);
			}

			// we might skip the '-run' param when running only testify methods, which will result
			// in running all the test methods, but one of them should call testify's `suite.Run(...)`
			// which will result in the correct thing to happen
			if (testFunctions.length > 0) {
				if (testFunctions.length === 1) {
					params = params.concat(['-run', util.format('^%s$', testFunctions[0])]);
				} else {
					params = params.concat(['-run', util.format('^(%s)$', testFunctions.join('|'))]);
				}
			}
			if (testifyMethods.length > 0) {
				params = params.concat(['-testify.m', util.format('^(%s)$', testifyMethods.join('|'))]);
			}
		}
		return params;
	}

	if (testconfig.isBenchmark) {
		params = ['-bench', '.'];
	}
	return params;
}

function removeRunFlag(flags: string[]): void {
	const index: number = flags.indexOf('-run');
	if (index !== -1) {
		flags.splice(index, 2);
	}
}

export function importsTestify(syms: vscode.DocumentSymbol[]): boolean {
	if (!syms || syms.length === 0 || !syms[0]) {
		return false;
	}
	const children = syms[0].children;
	return children.some(
		(sym) =>
			sym.kind === vscode.SymbolKind.Namespace &&
			(sym.name === '"github.com/stretchr/testify/suite"' || sym.name === 'github.com/stretchr/testify/suite')
	);
}
