/* 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 { getTextEditForAddImport } from '../../goImport';
import { promptForMissingTool, promptForUpdatingTool } from '../../goInstallTools';
import { isModSupported } from '../../goModules';
import { getImportablePackages, PackageInfo } from '../../goPackages';
import {
	byteOffsetAt,
	getBinPath,
	getCurrentGoPath,
	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 = false;
	private setGocodeOptions = true;
	private isGoMod = false;
	private globalState: vscode.Memento | undefined;
	private previousFile?: string;
	private previousFileDir?: string;
	private gocodeFlags?: string[];
	private excludeDocs = 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;
		}

		let { label } = item;
		if (typeof label !== 'string') label = label.label;

		return runGodoc(
			path.dirname(item.fileName),
			item.package || path.dirname(item.fileName),
			item.receiver,
			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 v = parseFilePrelude(vscode.window.activeTextEditor?.document.getText() ?? '');
							const pkg = v.pkg;
							if (!pkg) return;
							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 && this.gocodeFlags) {
				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') ?? -1;
			if (excludeDocsIndex >= 0 && this.gocodeFlags) {
				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') {
								let { label } = item;
								if (typeof label !== 'string') label = label.label;
								const possiblePackageImportPaths = this.getPackageImportPath(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 got = getParametersAndReturnType(suggest.type.substring(4));
								const params = got.params;
								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) => {
			const gocode = getBinPath('gocode');
			const env = toolExecutionEnvironment();

			cp.execFile(gocode, ['set'], { env }, (err, stdout) => {
				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 | undefined {
	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 | undefined;
		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;
}
