/*---------------------------------------------------------
 * 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 { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import {
	byteOffsetAt,
	canonicalizeGOPATHPrefix,
	getBinPath,
	getGoConfig,
	getWorkspaceFolderPath
} from './util';
import { envPath, getCurrentGoRoot } from './utils/goPath';
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, stderr) => {
					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, guruStdErr) => {
						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));
		});
	}
}
