/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import path = require('path');
import { DocumentSymbol, FileType, Uri, TextDocument, SymbolKind, Range, Position } from 'vscode';
import { packagePathToGoModPathMap } from '../../src/goModules';
import { GoTestExplorer } from '../../src/goTest/explore';
import { Workspace } from '../../src/goTest/utils';
import { MockTestWorkspace } from '../mocks/MockTest';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function getSymbols_Regex(doc: TextDocument, token: unknown): Thenable<DocumentSymbol[]> {
	const syms: DocumentSymbol[] = [];
	const range = new Range(new Position(0, 0), new Position(0, 0));
	doc.getText().replace(/^func (Test|Benchmark|Example)([A-Z]\w+)(\(.*\))/gm, (m, type, name, details) => {
		syms.push(new DocumentSymbol(type + name, details, SymbolKind.Function, range, range));
		return m;
	});
	return Promise.resolve(syms);
}

export function populateModulePathCache(workspace: MockTestWorkspace) {
	function walk(dir: Uri, modpath?: string) {
		const dirs: Uri[] = [];
		for (const [name, type] of workspace.fs.dirs.get(dir.toString())) {
			const uri = dir.with({ path: path.join(dir.path, name) });
			if (type === FileType.Directory) {
				dirs.push(uri);
			} else if (name === 'go.mod') {
				modpath = dir.path;
			}
		}
		packagePathToGoModPathMap[dir.path] = modpath || '';
		for (const dir of dirs) {
			walk(dir, modpath);
		}
	}

	// prevent getModFolderPath from actually doing anything;
	for (const pkg in packagePathToGoModPathMap) {
		delete packagePathToGoModPathMap[pkg];
	}
	walk(Uri.file('/'));
}

export async function forceDidOpenTextDocument(
	workspace: Workspace,
	testExplorer: GoTestExplorer,
	uri: Uri
): Promise<TextDocument> {
	const doc = await workspace.openTextDocument(uri);

	// Force didOpenTextDocument to fire. Without this, the test may run
	// before the event is handled.
	//
	// eslint-disable-next-line @typescript-eslint/no-explicit-any
	await (testExplorer as any).didOpenTextDocument(doc);

	return doc;
}
