/*---------------------------------------------------------
 * 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 { getTextEditForAddImport } from './goImport';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import { isModSupported } from './goModules';
import { getImportablePackages, PackageInfo } from './goPackages';
import {
	byteOffsetAt,
	getBinPath,
	getCurrentGoPath,
	getGoConfig,
	getParametersAndReturnType,
	goBuiltinTypes,
	goKeywords,
	guessPackageNameFromFile,
	isPositionInComment,
	isPositionInString,
	parseFilePrelude,
	runGodoc
} from './util';
import { getCurrentGoWorkspaceFromGOPATH } from './utils/pathUtils';

function vscodeKindFromGoCodeClass(kind: string, type: string): vscode.CompletionItemKind {
	switch (kind) {
		case 'const':
			return vscode.CompletionItemKind.Constant;
		case 'package':
			return vscode.CompletionItemKind.Module;
		case 'type':
			switch (type) {
				case 'struct':
					return vscode.CompletionItemKind.Class;
				case 'interface':
					return vscode.CompletionItemKind.Interface;
			}
			return vscode.CompletionItemKind.Struct;
		case 'func':
			return vscode.CompletionItemKind.Function;
		case 'var':
			return vscode.CompletionItemKind.Variable;
		case 'import':
			return vscode.CompletionItemKind.Module;
	}
	return vscode.CompletionItemKind.Property; // TODO@EG additional mappings needed?
}

interface GoCodeSuggestion {
	class: string;
	package?: string;
	name: string;
	type: string;
	receiver?: string;
}

class ExtendedCompletionItem extends vscode.CompletionItem {
	public package?: string;
	public receiver?: string;
	public fileName: string;
}

const lineCommentFirstWordRegex = /^\s*\/\/\s+[\S]*$/;
const exportedMemberRegex = /(const|func|type|var)(\s+\(.*\))?\s+([A-Z]\w*)/;
const gocodeNoSupportForgbMsgKey = 'dontshowNoSupportForgb';

export class GoCompletionItemProvider implements vscode.CompletionItemProvider, vscode.Disposable {
	private pkgsList = new Map<string, PackageInfo>();
	private killMsgShown: boolean = false;
	private setGocodeOptions: boolean = true;
	private isGoMod: boolean = false;
	private globalState: vscode.Memento;
	private previousFile: string;
	private previousFileDir: string;
	private gocodeFlags: string[];
	private excludeDocs: boolean = false;

	constructor(globalState?: vscode.Memento) {
		this.globalState = globalState;
	}

	public provideCompletionItems(
		document: vscode.TextDocument,
		position: vscode.Position,
		token: vscode.CancellationToken
	): Thenable<vscode.CompletionList> {
		return this.provideCompletionItemsInternal(document, position, token, getGoConfig(document.uri)).then(
			(result) => {
				if (!result) {
					return new vscode.CompletionList([], false);
				}
				if (Array.isArray(result)) {
					return new vscode.CompletionList(result, false);
				}
				return result;
			}
		);
	}

	public resolveCompletionItem(
		item: vscode.CompletionItem,
		token: vscode.CancellationToken
	): vscode.ProviderResult<vscode.CompletionItem> {
		if (
			!(item instanceof ExtendedCompletionItem) ||
			item.kind === vscode.CompletionItemKind.Module ||
			this.excludeDocs
		) {
			return;
		}

		if (typeof item.package === 'undefined') {
			promptForUpdatingTool('gocode');
			return;
		}

		return runGodoc(
			path.dirname(item.fileName),
			item.package || path.dirname(item.fileName),
			item.receiver,
			item.label,
			token
		)
			.then((doc) => {
				item.documentation = new vscode.MarkdownString(doc);
				return item;
			})
			.catch((err) => {
				console.log(err);
				return item;
			});
	}

	public async provideCompletionItemsInternal(
		document: vscode.TextDocument,
		position: vscode.Position,
		token: vscode.CancellationToken,
		config: vscode.WorkspaceConfiguration
	): Promise<vscode.CompletionItem[] | vscode.CompletionList> {
		// Completions for the package statement based on the file name
		const pkgStatementCompletions = await getPackageStatementCompletions(document);
		if (pkgStatementCompletions && pkgStatementCompletions.length) {
			return pkgStatementCompletions;
		}

		this.excludeDocs = false;
		this.gocodeFlags = ['-f=json'];
		if (Array.isArray(config['gocodeFlags'])) {
			this.gocodeFlags.push(...config['gocodeFlags']);
		}

		return this.ensureGoCodeConfigured(document.uri, config).then(() => {
			return new Promise<vscode.CompletionItem[] | vscode.CompletionList>((resolve, reject) => {
				const filename = document.fileName;
				const lineText = document.lineAt(position.line).text;
				const lineTillCurrentPosition = lineText.substr(0, position.character);
				const autocompleteUnimportedPackages =
					config['autocompleteUnimportedPackages'] === true && !lineText.match(/^(\s)*(import|package)(\s)+/);

				// triggering completions in comments on exported members
				const commentCompletion = getCommentCompletion(document, position);
				if (commentCompletion) {
					return resolve([commentCompletion]);
				}
				// prevent completion when typing in a line comment that doesnt start from the beginning of the line
				if (isPositionInComment(document, position)) {
					return resolve([]);
				}

				const inString = isPositionInString(document, position);
				if (!inString && lineTillCurrentPosition.endsWith('"')) {
					return resolve([]);
				}

				const currentWord = getCurrentWord(document, position);
				if (currentWord.match(/^\d+$/)) {
					return resolve([]);
				}

				let offset = byteOffsetAt(document, position);
				let inputText = document.getText();
				const includeUnimportedPkgs = autocompleteUnimportedPackages && !inString && currentWord.length > 0;

				return this.runGoCode(
					document,
					filename,
					inputText,
					offset,
					inString,
					position,
					lineText,
					currentWord,
					includeUnimportedPkgs,
					config
				).then((suggestions) => {
					// gocode does not suggest keywords, so we have to do it
					suggestions.push(...getKeywordCompletions(currentWord));

					// If no suggestions and cursor is at a dot, then check if preceeding word is a package name
					// If yes, then import the package in the inputText and run gocode again to get suggestions
					if ((!suggestions || suggestions.length === 0) && lineTillCurrentPosition.endsWith('.')) {
						const pkgPath = this.getPackagePathFromLine(lineTillCurrentPosition);
						if (pkgPath.length === 1) {
							// Now that we have the package path, import it right after the "package" statement
							const { imports, pkg } = parseFilePrelude(
								vscode.window.activeTextEditor.document.getText()
							);
							const posToAddImport = document.offsetAt(new vscode.Position(pkg.start + 1, 0));
							const textToAdd = `import "${pkgPath[0]}"\n`;
							inputText =
								inputText.substr(0, posToAddImport) + textToAdd + inputText.substr(posToAddImport);
							offset += textToAdd.length;

							// Now that we have the package imported in the inputText, run gocode again
							return this.runGoCode(
								document,
								filename,
								inputText,
								offset,
								inString,
								position,
								lineText,
								currentWord,
								false,
								config
							).then((newsuggestions) => {
								// Since the new suggestions are due to the package that we imported,
								// add additionalTextEdits to do the same in the actual document in the editor
								// We use additionalTextEdits instead of command so that 'useCodeSnippetsOnFunctionSuggest'
								// feature continues to work
								newsuggestions.forEach((item) => {
									item.additionalTextEdits = getTextEditForAddImport(pkgPath[0]);
								});
								resolve(newsuggestions);
							}, reject);
						}
						if (pkgPath.length > 1) {
							pkgPath.forEach((pkg) => {
								const item = new vscode.CompletionItem(
									`${lineTillCurrentPosition.replace('.', '').trim()} (${pkg})`,
									vscode.CompletionItemKind.Module
								);
								item.additionalTextEdits = getTextEditForAddImport(pkg);
								item.insertText = '';
								item.detail = pkg;
								item.command = {
									title: 'Trigger Suggest',
									command: 'editor.action.triggerSuggest'
								};
								suggestions.push(item);
							});
							resolve(new vscode.CompletionList(suggestions, true));
						}
					}
					resolve(suggestions);
				}, reject);
			});
		});
	}

	public dispose() {
		const gocodeName = this.isGoMod ? 'gocode-gomod' : 'gocode';
		const gocode = getBinPath(gocodeName);
		if (path.isAbsolute(gocode)) {
			cp.spawn(gocode, ['close'], { env: toolExecutionEnvironment() });
		}
	}

	private runGoCode(
		document: vscode.TextDocument,
		filename: string,
		inputText: string,
		offset: number,
		inString: boolean,
		position: vscode.Position,
		lineText: string,
		currentWord: string,
		includeUnimportedPkgs: boolean,
		config: vscode.WorkspaceConfiguration
	): Thenable<vscode.CompletionItem[]> {
		return new Promise<vscode.CompletionItem[]>((resolve, reject) => {
			const gocodeName = this.isGoMod ? 'gocode-gomod' : 'gocode';
			const gocode = getBinPath(gocodeName);
			if (!path.isAbsolute(gocode)) {
				promptForMissingTool(gocodeName);
				return reject();
			}

			const env = toolExecutionEnvironment();
			let stdout = '';
			let stderr = '';

			// stamblerre/gocode does not support -unimported-packages flags.
			if (this.isGoMod) {
				const unimportedPkgIndex = this.gocodeFlags.indexOf('-unimported-packages');
				if (unimportedPkgIndex >= 0) {
					this.gocodeFlags.splice(unimportedPkgIndex, 1);
				}
			}

			// -exclude-docs is something we use internally and is not related to gocode
			const excludeDocsIndex = this.gocodeFlags.indexOf('-exclude-docs');
			if (excludeDocsIndex >= 0) {
				this.gocodeFlags.splice(excludeDocsIndex, 1);
				this.excludeDocs = true;
			}

			// Spawn `gocode` process
			const p = cp.spawn(gocode, [...this.gocodeFlags, 'autocomplete', filename, '' + offset], { env });
			p.stdout.on('data', (data) => (stdout += data));
			p.stderr.on('data', (data) => (stderr += data));
			p.on('error', (err) => {
				if (err && (<any>err).code === 'ENOENT') {
					promptForMissingTool(gocodeName);
					return reject();
				}
				return reject(err);
			});
			p.on('close', (code) => {
				try {
					if (code !== 0) {
						if (stderr.indexOf(`rpc: can't find service Server.AutoComplete`) > -1 && !this.killMsgShown) {
							vscode.window.showErrorMessage(
								'Auto-completion feature failed as an older gocode process is still running. Please kill the running process for gocode and try again.'
							);
							this.killMsgShown = true;
						}
						if (stderr.startsWith('flag provided but not defined:')) {
							promptForUpdatingTool(gocodeName);
						}
						return reject();
					}
					const results = <[number, GoCodeSuggestion[]]>JSON.parse(stdout.toString());
					let suggestions: vscode.CompletionItem[] = [];
					const packageSuggestions: string[] = [];

					const wordAtPosition = document.getWordRangeAtPosition(position);
					let areCompletionsForPackageSymbols = false;
					if (results && results[1]) {
						for (const suggest of results[1]) {
							if (inString && suggest.class !== 'import') {
								continue;
							}
							const item = new ExtendedCompletionItem(suggest.name);
							item.kind = vscodeKindFromGoCodeClass(suggest.class, suggest.type);
							item.package = suggest.package;
							item.receiver = suggest.receiver;
							item.fileName = document.fileName;
							item.detail = suggest.type;
							if (!areCompletionsForPackageSymbols && item.package && item.package !== 'builtin') {
								areCompletionsForPackageSymbols = true;
							}
							if (suggest.class === 'package') {
								const possiblePackageImportPaths = this.getPackageImportPath(item.label);
								if (possiblePackageImportPaths.length === 1) {
									item.detail = possiblePackageImportPaths[0];
								}
								packageSuggestions.push(suggest.name);
							}
							if (inString && suggest.class === 'import') {
								item.textEdit = new vscode.TextEdit(
									new vscode.Range(
										position.line,
										lineText.substring(0, position.character).lastIndexOf('"') + 1,
										position.line,
										position.character
									),
									suggest.name
								);
							}
							if (
								(config['useCodeSnippetsOnFunctionSuggest'] ||
									config['useCodeSnippetsOnFunctionSuggestWithoutType']) &&
								((suggest.class === 'func' && lineText.substr(position.character, 2) !== '()') || // Avoids met() -> method()()
									(suggest.class === 'var' &&
										suggest.type.startsWith('func(') &&
										lineText.substr(position.character, 1) !== ')' && // Avoids snippets when typing params in a func call
										lineText.substr(position.character, 1) !== ',')) // Avoids snippets when typing params in a func call
							) {
								const { params, returnType } = getParametersAndReturnType(suggest.type.substring(4));
								const paramSnippets = [];
								for (let i = 0; i < params.length; i++) {
									let param = params[i].trim();
									if (param) {
										param = param.replace('${', '\\${').replace('}', '\\}');
										if (config['useCodeSnippetsOnFunctionSuggestWithoutType']) {
											if (param.includes(' ')) {
												// Separate the variable name from the type
												param = param.substr(0, param.indexOf(' '));
											}
										}
										paramSnippets.push('${' + (i + 1) + ':' + param + '}');
									}
								}
								item.insertText = new vscode.SnippetString(
									suggest.name + '(' + paramSnippets.join(', ') + ')'
								);
							}
							if (
								config['useCodeSnippetsOnFunctionSuggest'] &&
								suggest.class === 'type' &&
								suggest.type.startsWith('func(')
							) {
								const { params, returnType } = getParametersAndReturnType(suggest.type.substring(4));
								const paramSnippets = [];
								for (let i = 0; i < params.length; i++) {
									let param = params[i].trim();
									if (param) {
										param = param.replace('${', '\\${').replace('}', '\\}');
										if (!param.includes(' ')) {
											// If we don't have an argument name, we need to create one
											param = 'arg' + (i + 1) + ' ' + param;
										}
										const arg = param.substr(0, param.indexOf(' '));
										paramSnippets.push(
											'${' +
											(i + 1) +
											':' +
											arg +
											'}' +
											param.substr(param.indexOf(' '), param.length)
										);
									}
								}
								item.insertText = new vscode.SnippetString(
									suggest.name +
									'(func(' +
									paramSnippets.join(', ') +
									') {\n	$' +
									(params.length + 1) +
									'\n})' +
									returnType
								);
							}

							if (
								wordAtPosition &&
								wordAtPosition.start.character === 0 &&
								suggest.class === 'type' &&
								!goBuiltinTypes.has(suggest.name)
							) {
								const auxItem = new vscode.CompletionItem(
									suggest.name + ' method',
									vscode.CompletionItemKind.Snippet
								);
								auxItem.label = 'func (*' + suggest.name + ')';
								auxItem.filterText = suggest.name;
								auxItem.detail = 'Method snippet';
								auxItem.sortText = 'b';
								const prefix = 'func (' + suggest.name[0].toLowerCase() + ' *' + suggest.name + ')';
								const snippet = prefix + ' ${1:methodName}(${2}) ${3} {\n\t$0\n}';
								auxItem.insertText = new vscode.SnippetString(snippet);
								suggestions.push(auxItem);
							}

							// Add same sortText to all suggestions from gocode so that they appear before the unimported packages
							item.sortText = 'a';
							suggestions.push(item);
						}
					}

					// Add importable packages matching currentword to suggestions
					if (includeUnimportedPkgs && !this.isGoMod && !areCompletionsForPackageSymbols) {
						suggestions = suggestions.concat(
							getPackageCompletions(document, currentWord, this.pkgsList, packageSuggestions)
						);
					}

					resolve(suggestions);
				} catch (e) {
					reject(e);
				}
			});
			if (p.pid) {
				p.stdin.end(inputText);
			}
		});
	}
	// TODO: Shouldn't lib-path also be set?
	private ensureGoCodeConfigured(fileuri: vscode.Uri, goConfig: vscode.WorkspaceConfiguration): Thenable<void> {
		const currentFile = fileuri.fsPath;
		let checkModSupport = Promise.resolve(this.isGoMod);
		if (this.previousFile !== currentFile && this.previousFileDir !== path.dirname(currentFile)) {
			this.previousFile = currentFile;
			this.previousFileDir = path.dirname(currentFile);
			checkModSupport = isModSupported(fileuri).then((result) => (this.isGoMod = result));
		}
		const setPkgsList = getImportablePackages(currentFile, true).then((pkgMap) => {
			this.pkgsList = pkgMap;
		});

		if (!this.setGocodeOptions) {
			return Promise.all([checkModSupport, setPkgsList]).then(() => {
				return;
			});
		}

		const setGocodeProps = new Promise<void>((resolve, reject) => {
			const gocode = getBinPath('gocode');
			const env = toolExecutionEnvironment();

			cp.execFile(gocode, ['set'], { env }, (err, stdout, stderr) => {
				if (err && stdout.startsWith('gocode: unknown subcommand:')) {
					if (
						goConfig['gocodePackageLookupMode'] === 'gb' &&
						this.globalState &&
						!this.globalState.get(gocodeNoSupportForgbMsgKey)
					) {
						vscode.window
							.showInformationMessage(
								'The go.gocodePackageLookupMode setting for gb will not be honored as github.com/mdempskey/gocode doesnt support it yet.',
								`Don't show again`
							)
							.then((selected) => {
								if (selected === `Don't show again`) {
									this.globalState.update(gocodeNoSupportForgbMsgKey, true);
								}
							});
					}
					this.setGocodeOptions = false;
					return resolve();
				}

				const existingOptions = stdout.split(/\r\n|\n/);
				const optionsToSet: string[][] = [];
				const setOption = () => {
					const [name, value] = optionsToSet.pop();
					cp.execFile(gocode, ['set', name, value], { env }, () => {
						if (optionsToSet.length) {
							setOption();
						} else {
							resolve();
						}
					});
				};

				if (existingOptions.indexOf('propose-builtins true') === -1) {
					optionsToSet.push(['propose-builtins', 'true']);
				}
				if (existingOptions.indexOf(`autobuild ${goConfig['gocodeAutoBuild']}`) === -1) {
					optionsToSet.push(['autobuild', goConfig['gocodeAutoBuild']]);
				}
				if (existingOptions.indexOf(`package-lookup-mode ${goConfig['gocodePackageLookupMode']}`) === -1) {
					optionsToSet.push(['package-lookup-mode', goConfig['gocodePackageLookupMode']]);
				}
				if (!optionsToSet.length) {
					return resolve();
				}

				setOption();
			});
		});

		return Promise.all([setPkgsList, setGocodeProps, checkModSupport]).then(() => {
			return;
		});
	}

	// Given a line ending with dot, return the import paths of packages that match with the word preceeding the dot
	private getPackagePathFromLine(line: string): string[] {
		const pattern = /(\w+)\.$/g;
		const wordmatches = pattern.exec(line);
		if (!wordmatches) {
			return [];
		}

		const [_, pkgNameFromWord] = wordmatches;
		// Word is isolated. Now check pkgsList for a match
		return this.getPackageImportPath(pkgNameFromWord);
	}

	/**
	 * Returns import path for given package. Since there can be multiple matches,
	 * this returns an array of matches
	 * @param input Package name
	 */
	private getPackageImportPath(input: string): string[] {
		const matchingPackages: any[] = [];
		this.pkgsList.forEach((info: PackageInfo, pkgPath: string) => {
			if (input === info.name) {
				matchingPackages.push(pkgPath);
			}
		});
		return matchingPackages;
	}
}

/**
 * Provides completion item for the exported member in the next line if current line is a comment
 * @param document The current document
 * @param position The cursor position
 */
function getCommentCompletion(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem {
	const lineText = document.lineAt(position.line).text;
	const lineTillCurrentPosition = lineText.substr(0, position.character);
	// triggering completions in comments on exported members
	if (lineCommentFirstWordRegex.test(lineTillCurrentPosition) && position.line + 1 < document.lineCount) {
		const nextLine = document.lineAt(position.line + 1).text.trim();
		const memberType = nextLine.match(exportedMemberRegex);
		let suggestionItem: vscode.CompletionItem;
		if (memberType && memberType.length === 4) {
			suggestionItem = new vscode.CompletionItem(memberType[3], vscodeKindFromGoCodeClass(memberType[1], ''));
		}
		return suggestionItem;
	}
}

function getCurrentWord(document: vscode.TextDocument, position: vscode.Position): string {
	// get current word
	const wordAtPosition = document.getWordRangeAtPosition(position);
	let currentWord = '';
	if (wordAtPosition && wordAtPosition.start.character < position.character) {
		const word = document.getText(wordAtPosition);
		currentWord = word.substr(0, position.character - wordAtPosition.start.character);
	}

	return currentWord;
}

function getKeywordCompletions(currentWord: string): vscode.CompletionItem[] {
	if (!currentWord.length) {
		return [];
	}
	const completionItems: vscode.CompletionItem[] = [];
	goKeywords.forEach((keyword) => {
		if (keyword.startsWith(currentWord)) {
			completionItems.push(new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword));
		}
	});
	return completionItems;
}

/**
 * Return importable packages that match given word as Completion Items
 * @param document Current document
 * @param currentWord The word at the cursor
 * @param allPkgMap Map of all available packages and their import paths
 * @param importedPackages List of imported packages. Used to prune imported packages out of available packages
 */
function getPackageCompletions(
	document: vscode.TextDocument,
	currentWord: string,
	allPkgMap: Map<string, PackageInfo>,
	importedPackages: string[] = []
): vscode.CompletionItem[] {
	const cwd = path.dirname(document.fileName);
	const goWorkSpace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), cwd);
	const workSpaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
	const currentPkgRootPath = (workSpaceFolder ? workSpaceFolder.uri.path : cwd).slice(goWorkSpace.length + 1);

	const completionItems: any[] = [];

	allPkgMap.forEach((info: PackageInfo, pkgPath: string) => {
		const pkgName = info.name;
		if (pkgName.startsWith(currentWord) && importedPackages.indexOf(pkgName) === -1) {
			const item = new vscode.CompletionItem(pkgName, vscode.CompletionItemKind.Keyword);
			item.detail = pkgPath;
			item.documentation = 'Imports the package';
			item.insertText = pkgName;
			item.command = {
				title: 'Import Package',
				command: 'go.import.add',
				arguments: [{ importPath: pkgPath, from: 'completion' }]
			};
			item.kind = vscode.CompletionItemKind.Module;

			// Unimported packages should appear after the suggestions from gocode
			const isStandardPackage = !item.detail.includes('.');
			item.sortText = isStandardPackage ? 'za' : pkgPath.startsWith(currentPkgRootPath) ? 'zb' : 'zc';
			completionItems.push(item);
		}
	});
	return completionItems;
}

async function getPackageStatementCompletions(document: vscode.TextDocument): Promise<vscode.CompletionItem[]> {
	// 'Smart Snippet' for package clause
	const inputText = document.getText();
	if (inputText.match(/package\s+(\w+)/)) {
		return [];
	}

	const pkgNames = await guessPackageNameFromFile(document.fileName);
	const suggestions = pkgNames.map((pkgName) => {
		const packageItem = new vscode.CompletionItem('package ' + pkgName);
		packageItem.kind = vscode.CompletionItemKind.Snippet;
		packageItem.insertText = 'package ' + pkgName + '\r\n\r\n';
		return packageItem;
	});
	return suggestions;
}
