/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/

// vscode.WorkspaceConfiguration.get() returns any type.

import * as semver from 'semver';
import * as vscode from 'vscode';
import { extensionId } from './const';
import { getFormatTool } from './language/legacy/goFormat';
import { getFromGlobalState, updateGlobalState } from './stateUtils';

/** getGoConfig is declared as an exported const rather than a function, so it can be stubbbed in testing. */
export const getGoConfig = (uri?: vscode.Uri) => {
	return getConfig('go', uri);
};

/** getGoplsConfig returns the user's gopls configuration. */
export function getGoplsConfig(uri?: vscode.Uri) {
	return getConfig('gopls', uri);
}

function getConfig(section: string, uri?: vscode.Uri | null) {
	if (!uri) {
		if (vscode.window.activeTextEditor) {
			uri = vscode.window.activeTextEditor.document.uri;
		} else {
			uri = null;
		}
	}
	return vscode.workspace.getConfiguration(section, uri);
}

/** ExtensionInfo is a collection of static information about the extension. */
export class ExtensionInfo {
	/** Extension version */
	readonly version?: string;
	/** The application name of the editor, like 'VS Code' */
	readonly appName: string;
	/** True if the extension runs in preview mode (e.g. Nightly, prerelease) */
	readonly isPreview: boolean;
	/** True if the extension runs in well-known cloud IDEs */
	readonly isInCloudIDE: boolean;

	constructor() {
		const packageJSON = vscode.extensions.getExtension(extensionId)?.packageJSON;
		const version = semver.parse(packageJSON?.version);
		this.version = version?.format();
		this.appName = vscode.env.appName;

		// golang.go prerelease: minor version is an odd number, or has the "-dev" suffix.
		this.isPreview =
			extensionId === 'golang.go' && !!version
				? version.minor % 2 === 1 || version.toString().endsWith('-dev')
				: false;
		this.isInCloudIDE =
			process.env.CLOUD_SHELL === 'true' ||
			process.env.MONOSPACE_ENV === 'true' ||
			process.env.CODESPACES === 'true' ||
			!!process.env.GITPOD_WORKSPACE_ID;
	}
}

export const extensionInfo = new ExtensionInfo();

/**
 * FORMATTER_SUGGESTION_PREFIX_KEY is the prefix of key storing whether we
 * we have suggested user to switch from the formatter they configured
 * through "go.formatTool" to "gopls".
 * The corresponding value is type boolean indicating whether we have suggested
 * or not.
 * Right now, the only formatters we are suggesting to user are gofmt and gofumpt.
 */
export const FORMATTER_SUGGESTION_PREFIX_KEY = 'formatter-suggestion-';

/**
 * Performs cross-validation between the 'go' and 'gopls' configurations.
 *
 * This function's purpose is to detect conflicts where a setting in 'go'
 * impacts the behavior of the gopls. It should be called when relevant
 * settings in either configuration change.
 *
 * Note: This does not validate gopls settings internally, as the gopls
 * server is responsible for that itself.
 */
export async function validateConfig(
	goConfig: vscode.WorkspaceConfiguration,
	goplsConfig: vscode.WorkspaceConfiguration
) {
	// Lint tool check.
	const lintTool = goConfig.get<string>('lintTool');
	if (lintTool && lintTool === 'staticcheck' && goplsStaticcheckEnabled(goConfig, goplsConfig)) {
		const message = `Warning: staticcheck is configured to run both client side (go.lintTool=staticcheck) and server side (gopls.ui.diagnostic.staticcheck=true).
This will result in duplicate diagnostics.`;

		const selected = await vscode.window.showWarningMessage(message, 'Open Settings');
		if (selected === 'Open Settings') {
			vscode.commands.executeCommand('workbench.action.openSettingsJson');
		}
	}

	// Format tool check.
	const formatTool = getFormatTool(goConfig);
	if (formatTool === 'customFormatter') {
		const alternateTools = goConfig.get<any>('alternateTools');
		if (alternateTools === undefined || alternateTools['customFormatter'] === undefined) {
			const message =
				"Error: formatter is configured to custom (go.formatTool=custom) but custom formatter path is not provided in go.alternateTools['customFormatter']";

			const selected = await vscode.window.showWarningMessage(message, 'Open Settings');
			if (selected === 'Open Settings') {
				vscode.commands.executeCommand('workbench.action.openSettingsJson');
			}
		}
	}

	if (formatTool !== '' && goplsConfig['formatting.gofumpt'] === true) {
		const message = `Warning: formatter is configured to run from both client side (go.formatTool=${formatTool}) and server side (gopls.formatting.gofumpt=true).
This may result in double formatting.`;

		const selected = await vscode.window.showWarningMessage(message, 'Open Settings');
		if (selected === 'Open Settings') {
			vscode.commands.executeCommand('workbench.action.openSettingsJson');
		}
	}

	if (formatTool === 'gofumpt' || formatTool === 'gofmt') {
		const key = FORMATTER_SUGGESTION_PREFIX_KEY + formatTool;

		const suggested = getFromGlobalState(key, false);
		if (!suggested) {
			updateGlobalState(key, true);
			let instructions = 'change "go.formatTool" to default value'; // gopls will use gofmt by default.
			if (formatTool === 'gofumpt') {
				instructions += ' , set "gopls.formatting.gofumpt" to true'; // gofumpt need to be enabled explicitly.
			}
			const message = `Recommendation: the format tool ${formatTool} specified is available in gopls. You can enable it by: ${instructions}`;

			const selected = await vscode.window.showWarningMessage(message, 'Open Settings');
			if (selected === 'Open Settings') {
				vscode.commands.executeCommand('workbench.action.openSettingsJson');
			}
		}
	}
}

/**
 * Checks if the staticcheck analyzer is enabled in the gopls configuration.
 *
 * @param goConfig The 'go' extension configuration.
 * @param goplsConfig The 'gopls' configuration.
 * @returns true if staticcheck is enabled in gopls, false otherwise.
 */
export function goplsStaticcheckEnabled(
	goConfig: vscode.WorkspaceConfiguration,
	goplsConfig: vscode.WorkspaceConfiguration
): boolean {
	if (!goConfig.get<boolean>('useLanguageServer')) {
		return false;
	}

	/**
	 * Direct property access is used here instead of the standard
	 * `goplsConfig.get()` method.
	 *
	 * The `.get('a.b')` API interprets dots as a path to a nested property.
	 * However, 'gopls' configuration object has "flattened" keys that literally
	 * contain dots (e.g., the key is the string 'ui.diagnostic.staticcheck').
	 * Bracket notation is the only way to access such a property.
	 */
	if (goplsConfig['ui.diagnostic.staticcheck'] === false) {
		return false;
	}

	// "ui.diagnostic.staticcheck" unset or true means partially enabled and
	// fully enabled.
	// See https://go.googlesource.com/tools/+/refs/heads/master/gopls/doc/analyzers.md
	return true;
}
