/*---------------------------------------------------------
 * Copyright 2022 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import vscode = require('vscode');
import vscodeUri = require('vscode-uri');
import os = require('os');
import path = require('path');
import { getGoConfig } from './config';
import { getBinPath } from './util';
import { getRequiredTools } from './goTools';
import { inspectGoToolVersion } from './goInstallTools';
import { runGoEnv } from './goModules';

/**
 * GoExplorerProvider provides data for the Go tree view in the Explorer
 * Tree View Container.
 */
export class GoExplorerProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
	private goEnvCache = new Cache((uri) => GoEnv.get(uri ? vscode.Uri.parse(uri) : undefined), Time.MINUTE);
	private toolDetailCache = new Cache((name) => getToolDetail(name), Time.HOUR);
	private activeFolder?: vscode.WorkspaceFolder;
	private activeDocument?: vscode.TextDocument;

	static setup(ctx: vscode.ExtensionContext) {
		const provider = new this(ctx);
		const {
			window: { registerTreeDataProvider },
			commands: { registerCommand, executeCommand }
		} = vscode;
		ctx.subscriptions.push(
			registerTreeDataProvider('go.explorer', provider),
			registerCommand('go.explorer.refresh', () => provider.update(true)),
			registerCommand('go.explorer.open', (item) => provider.open(item)),
			registerCommand('go.workspace.editEnv', (item) => provider.editEnv(item)),
			registerCommand('go.workspace.resetEnv', (item) => provider.resetEnv(item))
		);
		executeCommand('setContext', 'go.showExplorer', true);
		return provider;
	}

	private _onDidChangeTreeData = new vscode.EventEmitter<vscode.TreeItem | void>();
	readonly onDidChangeTreeData = this._onDidChangeTreeData.event;

	constructor(ctx: vscode.ExtensionContext) {
		this.update();
		ctx.subscriptions.push(
			vscode.window.onDidChangeActiveTextEditor(() => this.update()),
			vscode.workspace.onDidChangeWorkspaceFolders(() => this.update()),
			vscode.workspace.onDidChangeConfiguration(() => this.update(true)),
			vscode.workspace.onDidCloseTextDocument((doc) => {
				if (!this.activeFolder) {
					this.goEnvCache.delete(vscodeUri.Utils.dirname(doc.uri).toString());
				}
			})
		);
	}

	getTreeItem(element: vscode.TreeItem) {
		return element;
	}

	getChildren(element?: vscode.TreeItem) {
		if (!element) {
			return [this.envTree(), this.toolTree()];
		}
		if (isEnvTree(element)) {
			return this.envTreeItems(element.workspace);
		}
		if (isToolTree(element)) {
			return this.toolTreeItems();
		}
		if (isToolTreeItem(element)) {
			return element.children;
		}
	}

	private update(clearCache = false) {
		if (clearCache) {
			this.goEnvCache.clear();
			this.toolDetailCache.clear();
		}
		const { activeTextEditor } = vscode.window;
		const { getWorkspaceFolder, workspaceFolders } = vscode.workspace;
		this.activeDocument = activeTextEditor?.document;
		this.activeFolder = activeTextEditor?.document
			? getWorkspaceFolder(activeTextEditor.document.uri) || workspaceFolders?.[0]
			: workspaceFolders?.[0];
		this._onDidChangeTreeData.fire();
	}

	private async open(item: EnvTreeItem) {
		if (typeof item.file === 'undefined') return;
		const edit = new vscode.WorkspaceEdit();
		edit.createFile(item.file, { ignoreIfExists: true });
		await vscode.workspace.applyEdit(edit);
		const doc = await vscode.workspace.openTextDocument(item.file);
		await vscode.window.showTextDocument(doc);
	}

	private async editEnv(item?: EnvTreeItem) {
		const uri = this.activeFolder?.uri;
		if (!uri) {
			return;
		}
		let pick: { label?: string; description?: string } | undefined;
		if (isEnvTreeItem(item)) {
			pick = { label: item.key, description: item.value };
		} else {
			const items = Object.entries<string>(await runGoEnv(uri))
				.filter(([label]) => !GoEnv.readonlyVars.has(label))
				.map(([label, description]) => ({
					label,
					description
				}));
			pick = await vscode.window.showQuickPick(items, { title: 'Go: Edit Workspace Env' });
		}
		if (!pick) return;
		const { label, description } = pick;
		const value = await vscode.window.showInputBox({ title: label, value: description });
		if (label && typeof value !== 'undefined') {
			await GoEnv.edit({ [label]: value });
		}
	}

	private async resetEnv(item?: EnvTreeItem) {
		if (item?.key) {
			await GoEnv.reset([item.key]);
			return;
		}
		await GoEnv.reset();
	}

	private envTree() {
		if (this.activeFolder) {
			const { name, uri } = this.activeFolder;
			return new EnvTree(name, uri);
		}
		if (this.activeDocument) {
			const { fileName, uri } = this.activeDocument;
			return new EnvTree(path.basename(fileName), vscodeUri.Utils.dirname(uri));
		}
		return new EnvTree();
	}

	private async envTreeItems(uri?: vscode.Uri) {
		const env = await this.goEnvCache.get(uri?.toString() ?? '');
		const items = [];
		for (const [k, v] of Object.entries(env)) {
			if (v !== '') {
				items.push(new EnvTreeItem(k, v));
			}
		}
		return items;
	}

	private toolTree() {
		return new ToolTree();
	}

	private async toolTreeItems() {
		const allTools = getRequiredTools(getGoConfig());
		const toolsInfo = await Promise.all(allTools.map((tool) => this.toolDetailCache.get(tool.name)));
		const items = [];
		for (const t of toolsInfo) {
			items.push(new ToolTreeItem(t));
		}
		return items;
	}
}

class EnvTree implements vscode.TreeItem {
	label = 'env';
	contextValue = 'go:explorer:envtree';
	collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
	iconPath = new vscode.ThemeIcon('symbol-folder');
	constructor(public description = '', public workspace?: vscode.Uri) {}
}

function isEnvTree(item?: vscode.TreeItem): item is EnvTree {
	return item?.contextValue === 'go:explorer:envtree';
}

class EnvTreeItem implements vscode.TreeItem {
	file?: vscode.Uri;
	label: string;
	contextValue?: string;
	tooltip?: string;
	constructor(public key: string, public value: string) {
		this.label = `${key}=${replaceHome(value)}`;
		this.contextValue = 'go:explorer:envitem';
		if (GoEnv.fileVars.has(key)) {
			this.contextValue = 'go:explorer:envfile';
			this.file = vscode.Uri.file(value);
		}
		this.tooltip = `${key}=${value}`;
	}
}

function isEnvTreeItem(item?: vscode.TreeItem): item is EnvTreeItem {
	return item?.contextValue === 'go:explorer:envitem';
}

class GoEnv {
	/**
	 * get returns a subset of go env vars, the union of this.vars and values
	 * set with toolsEnvVars in the go workspace config.
	 * @param uri the directory from which to run go env.
	 * @returns the output of running go env -json VAR1 VAR2...
	 */
	static async get(uri?: vscode.Uri) {
		const toolsEnv = await getGoConfig(uri)['toolsEnvVars'];
		const output = await runGoEnv(uri, [...this.vars, ...Object.keys(toolsEnv)]);
		return output as Record<string, string>;
	}

	/**
	 * update writes to toolsEnvVars in the go workspace config.
	 * @param vars a record of env vars to update.
	 */
	static async edit(vars: Record<string, string>) {
		const config = getGoConfig();
		await config.update('toolsEnvVars', { ...config['toolsEnvVars'], ...vars });
	}

	/**
	 * reset removes entries from toolsEnvVars in the go workspace config.
	 * @param vars env vars to reset.
	 */
	static async reset(vars?: string[]) {
		const config = getGoConfig();
		let env: Record<string, string> = {};
		if (vars) {
			env = { ...config['toolsEnvVars'] };
			for (const v of vars) {
				delete env[v];
			}
		}
		await config.update('toolsEnvVars', env);
	}

	/** Vars that point to files. */
	static fileVars = new Set(['GOMOD', 'GOWORK', 'GOENV']);

	/** Vars available from 'go env' but not read from the environment */
	static readonlyVars = new Set([
		'GOEXE',
		'GOGCCFLAGS',
		'GOHOSTARCH',
		'GOHOSTOS',
		'GOMOD',
		'GOTOOLDIR',
		'GOVERSION',
		'GOWORK'
	]);

	/** Vars that should always be visible if they contain a value. */
	private static vars = ['GOPRIVATE', 'GOMOD', 'GOWORK', 'GOENV', 'GOTOOLCHAIN'];
}

class ToolTree implements vscode.TreeItem {
	label = 'tools';
	contextValue = 'go:explorer:tools';
	collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
	iconPath = new vscode.ThemeIcon('tools');
}

function isToolTree(item?: vscode.TreeItem): item is ToolTree {
	return item?.contextValue === 'go:explorer:tools';
}

class ToolTreeItem implements vscode.TreeItem {
	contextValue = 'go:explorer:toolitem';
	description = 'not installed';
	label: string;
	children?: vscode.TreeItem[];
	collapsibleState?: vscode.TreeItemCollapsibleState;
	tooltip?: string;
	constructor({ name, version, goVersion, binPath, error }: ToolDetail) {
		this.label = name;
		if (binPath) {
			this.label = `${name}@${version}`;
			this.description = `${replaceHome(binPath)} ${goVersion}`;
			this.tooltip = `${this.label} ${this.description}`;
		}
		if (error) {
			const msg = `go version -m failed: ${error}`;
			this.description = msg;
			this.tooltip = msg;
		}
	}
}

function isToolTreeItem(item?: vscode.TreeItem): item is ToolTreeItem {
	return item?.contextValue === 'go:explorer:toolitem';
}

interface ToolDetail {
	name: string;
	goVersion?: string;
	version?: string;
	binPath?: string;
	error?: Error;
}

async function getToolDetail(name: string): Promise<ToolDetail> {
	const toolPath = getBinPath(name);
	if (!path.isAbsolute(toolPath)) {
		return { name: name };
	}
	try {
		const { goVersion, moduleVersion } = await inspectGoToolVersion(toolPath);
		return {
			name: name,
			binPath: toolPath,
			goVersion: goVersion,
			version: moduleVersion
		};
	} catch (e) {
		return { name: name, error: e as Error };
	}
}

const enum Time {
	SECOND = 1000,
	MINUTE = SECOND * 60,
	HOUR = MINUTE * 60
}

interface CacheEntry<T> {
	entry: T;
	updatedAt: number;
}

class Cache<T> {
	private cache = new Map<string, CacheEntry<T>>();

	constructor(private fn: (key: string) => Promise<T>, private ttl: number) {}

	async get(key: string, ttl = this.ttl) {
		const cache = this.cache.get(key);
		const useCache = cache && Date.now() - cache.updatedAt < ttl;
		if (useCache) {
			return cache.entry;
		}
		const entry = await this.fn(key);
		this.cache.set(key, { entry, updatedAt: Date.now() });
		return entry;
	}

	clear() {
		return this.cache.clear();
	}

	delete(key: string) {
		return this.cache.delete(key);
	}
}

/**
 * replaceHome replaces the home directory prefix of a string with `~`.
 * @param maybePath a string that might be a file system path.
 * @returns the string with os.homedir() replaced by `~`.
 */
function replaceHome(maybePath: string) {
	return maybePath.replace(new RegExp(`^${os.homedir()}`), '~');
}
