/* 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.
 *--------------------------------------------------------*/

'use strict';

import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
import { getGoConfig } from './config';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath, getWorkspaceFolderPath } from './util';
import { envPath, getCurrentGoRoot } from './utils/pathUtils';
import { killProcessTree } from './utils/processUtils';

interface GoListOutput {
	Dir: string;
	ImportPath: string;
	Root: string;
}

interface GuruImplementsRef {
	name: string;
	pos: string;
	kind: string;
}

interface GuruImplementsOutput {
	type: GuruImplementsRef;
	to: GuruImplementsRef[];
	to_method: GuruImplementsRef[];
	from: GuruImplementsRef[];
	fromptr: GuruImplementsRef[];
}

export class GoImplementationProvider implements vscode.ImplementationProvider {
	public provideImplementation(
		document: vscode.TextDocument,
		position: vscode.Position,
		token: vscode.CancellationToken
	): Thenable<vscode.Definition> {
		// To keep `guru implements` fast we want to restrict the scope of the search to current workspace
		// If no workspace is open, then no-op
		const root = getWorkspaceFolderPath(document.uri);
		if (!root) {
			vscode.window.showInformationMessage('Cannot find implementations when there is no workspace open.');
			return;
		}

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

		return new Promise<vscode.Definition>((resolve, reject) => {
			if (token.isCancellationRequested) {
				return resolve(null);
			}
			const env = toolExecutionEnvironment();
			const listProcess = cp.execFile(
				goRuntimePath,
				['list', '-e', '-json'],
				{ cwd: root, env },
				(err, stdout) => {
					if (err) {
						return reject(err);
					}
					const listOutput = <GoListOutput>JSON.parse(stdout.toString());
					const filename = canonicalizeGOPATHPrefix(document.fileName);
					const cwd = path.dirname(filename);
					const offset = byteOffsetAt(document, position);
					const goGuru = getBinPath('guru');
					const buildTags = getGoConfig(document.uri)['buildTags'];
					const args = buildTags ? ['-tags', buildTags] : [];
					if (listOutput.Root && listOutput.ImportPath) {
						args.push('-scope', `${listOutput.ImportPath}/...`);
					}
					args.push('-json', 'implements', `${filename}:#${offset.toString()}`);

					const guruProcess = cp.execFile(goGuru, args, { env }, (guruErr, guruStdOut) => {
						if (guruErr && (<any>guruErr).code === 'ENOENT') {
							promptForMissingTool('guru');
							return resolve(null);
						}

						if (guruErr) {
							return reject(guruErr);
						}

						const guruOutput = <GuruImplementsOutput>JSON.parse(guruStdOut.toString());
						const results: vscode.Location[] = [];
						const addResults = (list: GuruImplementsRef[]) => {
							list.forEach((ref: GuruImplementsRef) => {
								const match = /^(.*):(\d+):(\d+)/.exec(ref.pos);
								if (!match) {
									return;
								}
								const [, file, lineStartStr, colStartStr] = match;
								const referenceResource = vscode.Uri.file(path.resolve(cwd, file));
								const range = new vscode.Range(
									+lineStartStr - 1,
									+colStartStr - 1,
									+lineStartStr - 1,
									+colStartStr
								);
								results.push(new vscode.Location(referenceResource, range));
							});
						};

						// If we looked for implementation of method go to method implementations only
						if (guruOutput.to_method) {
							addResults(guruOutput.to_method);
						} else if (guruOutput.to) {
							addResults(guruOutput.to);
						} else if (guruOutput.from) {
							addResults(guruOutput.from);
						} else if (guruOutput.fromptr) {
							addResults(guruOutput.fromptr);
						}

						return resolve(results);
					});
					token.onCancellationRequested(() => killProcessTree(guruProcess));
				}
			);
			token.onCancellationRequested(() => killProcessTree(listProcess));
		});
	}
}
