/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable node/no-unpublished-import */
/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import assert from 'assert';
import * as path from 'path';
import * as vscode from 'vscode';
import { getGoConfig } from '../../src/config';
import sinon = require('sinon');
import { getGoVersion, GoVersion } from '../../src/util';
import { GOPLS_MAYBE_PROMPT_FOR_TELEMETRY, TELEMETRY_START_TIME_KEY, TelemetryService } from '../../src/goTelemetry';
import { MockMemento } from '../mocks/MockMemento';
import { Env } from './goplsTestEnv.utils';

async function sleep(ms: number) {
	return new Promise((resolve) => setTimeout(resolve, ms));
}

suite('Go Extension Tests With Gopls', function () {
	this.timeout(300000);
	const projectDir = path.join(__dirname, '..', '..', '..');
	const testdataDir = path.join(projectDir, 'test', 'testdata');
	const env = new Env();
	const sandbox = sinon.createSandbox();
	let goVersion: GoVersion;

	suiteSetup(async () => {
		goVersion = await getGoVersion();
	});

	this.afterEach(async function () {
		await env.teardown();
		// Note: this shouldn't use () => {...}. Arrow functions do not have 'this'.
		// I don't know why but this.currentTest.state does not have the expected value when
		// used with teardown.
		env.flushTrace(this.currentTest?.state === 'failed');
		sandbox.restore();
	});

	test('HoverProvider', async () => {
		const workspaceDir = path.resolve(testdataDir, 'gogetdocTestData');
		await env.startGopls(path.join(workspaceDir, 'test.go'), undefined, workspaceDir);
		const { uri } = await env.openDoc(testdataDir, 'gogetdocTestData', 'test.go');
		const testCases: [string, vscode.Position, string | null, string | null][] = [
			// [new vscode.Position(3,3), '/usr/local/go/src/fmt'],
			['keyword', new vscode.Position(0, 3), null, null], // keyword
			['inside a string', new vscode.Position(23, 14), null, null], // inside a string
			['just a }', new vscode.Position(20, 0), null, null], // just a }
			['inside a number', new vscode.Position(28, 16), null, null], // inside a number
			['func main()', new vscode.Position(22, 5), 'func main()', null],
			['import "math"', new vscode.Position(40, 23), 'package math', '`math` on'],
			[
				'func Println()',
				new vscode.Position(19, 6),
				goVersion.lt('1.18')
					? 'func fmt.Println(a ...interface{}) (n int, err error)'
					: 'func fmt.Println(a ...any) (n int, err error)',
				'Println formats '
			],
			['func print()', new vscode.Position(23, 4), 'func print(txt string)', 'This is an unexported function ']
		];

		const promises = testCases.map(async ([name, position, expectedSignature, expectedDoc]) => {
			const hovers = (await vscode.commands.executeCommand(
				'vscode.executeHoverProvider',
				uri,
				position
			)) as vscode.Hover[];

			if (expectedSignature === null && expectedDoc === null) {
				assert.equal(hovers.length, 0, `check hovers over ${name} failed: unexpected non-empty hover message.`);
				return;
			}

			const hover = hovers[0];
			assert.equal(
				hover.contents.length,
				1,
				`check hovers over ${name} failed: unexpected number of hover messages.`
			);
			const gotMessage = (<vscode.MarkdownString>hover.contents[0]).value;
			assert.ok(
				gotMessage.includes('```go\n' + expectedSignature + '\n```') &&
					(!expectedDoc || gotMessage.includes(expectedDoc)),
				`check hovers over ${name} failed: got ${gotMessage}`
			);
		});
		return Promise.all(promises);
	});

	test('Completion middleware', async () => {
		const workspaceDir = path.resolve(testdataDir, 'gogetdocTestData');
		await env.startGopls(path.join(workspaceDir, 'test.go'), undefined, workspaceDir);
		const { uri } = await env.openDoc(testdataDir, 'gogetdocTestData', 'test.go');
		const testCases: [string, vscode.Position, string, vscode.CompletionItemKind][] = [
			['fmt.P<>', new vscode.Position(19, 6), 'Print', vscode.CompletionItemKind.Function],
			['xyz.H<>', new vscode.Position(41, 13), 'Hello', vscode.CompletionItemKind.Method]
		];

		for (const [name, position, wantFilterText, wantItemKind] of testCases) {
			let list: vscode.CompletionList<vscode.CompletionItem> | undefined;
			// Query completion items. We expect the hard coded filter text hack
			// has been applied and gopls returns an incomplete list by default
			// to avoid reordering by vscode. But, if the query is made before
			// gopls is ready, we observed that gopls returns an empty result
			// as a complete result, and vscode returns a general completion list instead.
			// Retry a couple of times if we see a complete result as a workaround.
			// (github.com/golang/vscode-go/issues/363)
			for (let i = 0; i < 3; i++) {
				list = (await vscode.commands.executeCommand(
					'vscode.executeCompletionItemProvider',
					uri,
					position
				)) as vscode.CompletionList;
				if (list.isIncomplete) {
					break;
				}
				await sleep(100);
				console.log(`${new Date()}: retrying...`);
			}
			// Confirm that the hardcoded filter text hack has been applied.
			if (!list || !list.isIncomplete) {
				assert.fail('gopls should provide an incomplete list by default');
			}

			// vscode.executeCompletionItemProvider will return results from all
			// registered completion item providers, not only gopls but also snippets.
			// Alternative is to directly query the language client, but that will
			// prevent us from detecting problems caused by issues between the language
			// client library and the vscode.
			let itemKindFound = false;
			for (const item of list.items) {
				if (item.kind === vscode.CompletionItemKind.Snippet) {
					continue;
				} // gopls does not supply Snippet yet.
				assert.strictEqual(
					item.filterText ?? item.label,
					wantFilterText,
					`${uri}:${name} failed, unexpected filter text ` +
						`(got ${item.filterText ?? item.label}, want ${wantFilterText})\n` +
						`${JSON.stringify(item, null, 2)}`
				);
				if (item.kind === wantItemKind) {
					itemKindFound = true;
				}
				if (
					item.kind === vscode.CompletionItemKind.Method ||
					item.kind === vscode.CompletionItemKind.Function
				) {
					assert.ok(
						item.command,
						`${uri}:${name}: expected command associated with ${item.label}, found none`
					);
				}
			}
			assert(itemKindFound, `failed to find expected item kind ${wantItemKind}: got ${JSON.stringify(list)}`);
		}
	});

	async function testCustomFormatter(goConfig: vscode.WorkspaceConfiguration, customFormatter: string) {
		const config = require('../../src/config');
		sandbox.stub(config, 'getGoConfig').returns(goConfig);
		const workspaceDir = path.resolve(testdataDir, 'gogetdocTestData');
		await env.startGopls(path.join(workspaceDir, 'test.go'), goConfig, workspaceDir);
		const { doc } = await env.openDoc(testdataDir, 'gogetdocTestData', 'format.go');
		await vscode.window.showTextDocument(doc);

		const formatFeature = env.languageClient?.getFeature('textDocument/formatting');
		const formatter = formatFeature?.getProvider(doc);
		const tokensrc = new vscode.CancellationTokenSource();
		try {
			const result = await formatter?.provideDocumentFormattingEdits(
				doc,
				{} as vscode.FormattingOptions,
				tokensrc.token
			);
			assert.fail(`formatter unexpectedly succeeded and returned a result: ${JSON.stringify(result)}`);
		} catch (e) {
			assert(`${e}`.includes(`errors when formatting with ${customFormatter}`), `${e}`);
		}
	}

	test('Nonexistent formatter', async () => {
		const customFormatter = 'nonexistent';
		const goConfig = Object.create(getGoConfig(), {
			formatTool: { value: customFormatter } // this should make the formatter fail.
		}) as vscode.WorkspaceConfiguration;

		await testCustomFormatter(goConfig, customFormatter);
	});

	test('Custom formatter', async () => {
		const customFormatter = 'coolCustomFormatter';
		const goConfig = Object.create(getGoConfig(), {
			formatTool: { value: 'custom' }, // this should make the formatter fail.
			alternateTools: { value: { customFormatter: customFormatter } } // this should make the formatter fail.
		}) as vscode.WorkspaceConfiguration;

		await testCustomFormatter(goConfig, customFormatter);
	});

	test('Prompt For telemetry', async () => {
		const workspaceDir = path.resolve(testdataDir, 'gogetdocTestData');
		await env.startGopls(path.join(workspaceDir, 'test.go'), undefined, workspaceDir);
		const memento = new MockMemento();
		memento.update(TELEMETRY_START_TIME_KEY, new Date('2000-01-01'));

		const sut = new TelemetryService(env.languageClient, memento, [GOPLS_MAYBE_PROMPT_FOR_TELEMETRY]);
		try {
			await Promise.all([
				// we want to see the prompt command flowing.
				env.onMessageInTrace(GOPLS_MAYBE_PROMPT_FOR_TELEMETRY, 60_000),
				sut.promptForTelemetry(
					false /* not a preview */,
					true /* vscode telemetry not disabled */,
					1000 /* 1000 out of 1000 users */
				)
			]);
		} catch (e) {
			assert(false, `unexpected failure: ${e}`);
		}
	});
});
