/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable node/no-deprecated-api */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------*/

import * as assert from 'assert';
import * as vscode from 'vscode';
import { getGoConfig } from '../../src/config';
import * as lsp from '../../src/goLanguageServer';
import * as goInstallTools from '../../src/goInstallTools';
import { getTool, Tool } from '../../src/goTools';
import { getCheckForToolsUpdatesConfig as getCheckForToolUpdatesConfig } from '../../src/util';
import moment = require('moment');
import semver = require('semver');
import sinon = require('sinon');

suite('getCheckForToolUpdatesConfig tests', () => {
	const CHECK_FOR_UPDATES = 'toolsManagement.checkForUpdates';
	const LEGACY_CHECK_FOR_UPDATES = 'useGoProxyToCheckForToolUpdates';
	const defaultConfigInspector = getGoConfig().inspect(CHECK_FOR_UPDATES);

	test('default is as expected', () => {
		const { key, defaultValue, globalValue, workspaceValue } = defaultConfigInspector;
		assert.deepStrictEqual(
			{ key, defaultValue, globalValue, workspaceValue },
			{
				key: `go.${CHECK_FOR_UPDATES}`,
				defaultValue: 'proxy',
				globalValue: undefined,
				workspaceValue: undefined
			},
			CHECK_FOR_UPDATES
		);
		assert.strictEqual(getGoConfig().get(LEGACY_CHECK_FOR_UPDATES), true, LEGACY_CHECK_FOR_UPDATES);
	});

	// wrapper class of vscode.WorkspaceConfiguration - the object returned by
	// vscode.getConfiguration is read-only, and doesn't allow property modification
	// so working with sinon directly doesn't seem possible.
	class TestWorkspaceConfiguration implements vscode.WorkspaceConfiguration {
		constructor(private _wrapped: vscode.WorkspaceConfiguration) {}
		public get<T>(params: string) {
			return this._wrapped.get<T>(params);
		}
		public has(params: string) {
			return this._wrapped.has(params);
		}
		public inspect<T>(params: string) {
			return this._wrapped.inspect<T>(params);
		}
		public update<T>(
			section: string,
			value: any,
			configurationTarget?: vscode.ConfigurationTarget | boolean,
			overrideInLanguage?: boolean
		) {
			return this._wrapped.update(section, value, configurationTarget, overrideInLanguage);
		}
		[key: string]: any;
	}

	teardown(() => {
		sinon.restore();
	});

	test('default checkForUpdates returns proxy', () => {
		const gocfg = getGoConfig();
		assert.strictEqual(getCheckForToolUpdatesConfig(gocfg), 'proxy');
	});
	test('local when new config is not set and legacy config is set to false', () => {
		const gocfg = new TestWorkspaceConfiguration(getGoConfig());
		sinon.stub(gocfg, 'get').withArgs(LEGACY_CHECK_FOR_UPDATES).returns(false);

		assert.strictEqual(getCheckForToolUpdatesConfig(gocfg), 'local');
	});
	test('proxy when new config is "proxy" and legacy config is set to false', () => {
		const gocfg = new TestWorkspaceConfiguration(getGoConfig());
		sinon
			.stub(gocfg, 'get')
			.withArgs(LEGACY_CHECK_FOR_UPDATES)
			.returns(false)
			.withArgs(CHECK_FOR_UPDATES)
			.returns('proxy');
		sinon
			.stub(gocfg, 'inspect')
			.withArgs(CHECK_FOR_UPDATES)
			.returns(Object.assign({}, defaultConfigInspector, { globalValue: 'proxy' }));

		assert.strictEqual(getCheckForToolUpdatesConfig(gocfg), 'proxy');
	});
	test('off when new config (workspace) is "off" and legacy config is set to false', () => {
		const gocfg = new TestWorkspaceConfiguration(getGoConfig());
		sinon
			.stub(gocfg, 'get')
			.withArgs(LEGACY_CHECK_FOR_UPDATES)
			.returns(false)
			.withArgs(CHECK_FOR_UPDATES)
			.returns('off');
		sinon
			.stub(gocfg, 'inspect')
			.withArgs(CHECK_FOR_UPDATES)
			.returns(Object.assign({}, defaultConfigInspector, { workspaceValue: 'off' }));
		assert.strictEqual(getCheckForToolUpdatesConfig(gocfg), 'off');
	});
});

suite('gopls update tests', () => {
	test('prompt for update', async () => {
		const tool = getTool('gopls');

		const toSemver = (v: string) => semver.parse(v, { includePrerelease: true, loose: true });

		// Fake data stubbed functions will serve.
		const latestVersion = toSemver('0.4.1');
		const latestVersionTimestamp = moment('2020-05-13', 'YYYY-MM-DD');
		const latestPrereleaseVersion = toSemver('0.4.2-pre1');
		const latestPrereleaseVersionTimestamp = moment('2020-05-20', 'YYYY-MM-DD');

		// name, usersVersion, acceptPrerelease, want
		const testCases: [string, string, boolean, semver.SemVer][] = [
			['outdated, tagged', 'v0.3.1', false, latestVersion],
			['outdated, tagged (pre-release)', '0.3.1', true, latestPrereleaseVersion],
			['up-to-date, tagged', latestVersion.format(), false, null],
			['up-to-date tagged (pre-release)', 'v0.4.0', true, latestPrereleaseVersion],
			['developer version', '(devel)', false, null],
			['developer version (pre-release)', '(devel)', true, null],
			['nonsense version', 'nosuchversion', false, latestVersion],
			['nonsense version (pre-release)', 'nosuchversion', true, latestPrereleaseVersion],
			['latest pre-release', 'v0.4.2-pre1', false, null],
			['latest pre-release (pre-release)', 'v0.4.2-pre1', true, null],
			['outdated pre-release version', 'v0.3.1-pre1', false, latestVersion],
			['outdated pre-release version (pre-release)', 'v0.3.1-pre1', true, latestPrereleaseVersion],
			['recent pseudoversion after pre-release, 2020-05-20', 'v0.0.0-20200521000000-2212a7e161a5', false, null],
			['recent pseudoversion before pre-release, 2020-05-20', 'v0.0.0-20200515000000-2212a7e161a5', false, null],
			['recent pseudoversion after pre-release (pre-release)', 'v0.0.0-20200521000000-2212a7e161a5', true, null],
			[
				'recent pseudoversion before pre-release (pre-release)',
				'v0.0.0-20200515000000-2212a7e161a5',
				true,
				latestPrereleaseVersion
			],
			['outdated pseudoversion', 'v0.0.0-20200309030707-2212a7e161a5', false, latestVersion],
			[
				'outdated pseudoversion (pre-release)',
				'v0.0.0-20200309030707-2212a7e161a5',
				true,
				latestPrereleaseVersion
			]
		];
		for (const [name, usersVersion, acceptPrerelease, want] of testCases) {
			sinon.replace(lsp, 'getLocalGoplsVersion', async () => {
				return usersVersion;
			});
			sinon.replace(goInstallTools, 'latestToolVersion', async () => {
				if (acceptPrerelease) {
					return latestPrereleaseVersion;
				}
				return latestVersion;
			});
			sinon.replace(lsp, 'getTimestampForVersion', async (_: Tool, version: semver.SemVer) => {
				if (version === latestVersion) {
					return latestVersionTimestamp;
				}
				if (version === latestPrereleaseVersion) {
					return latestPrereleaseVersionTimestamp;
				}
			});
			const got = await lsp.shouldUpdateLanguageServer(tool, {
				enabled: true,
				path: 'bad/path/to/gopls',
				version: '',
				checkForUpdates: 'proxy',
				env: {},
				features: {
					diagnostics: true
				},
				flags: [],
				modtime: new Date(),
				serverName: 'gopls'
			});
			assert.deepEqual(got, want, `${name}: failed (got: '${got}' ${typeof got} want: '${want}' ${typeof want})`);
			sinon.restore();
		}
	});
});

suite('version comparison', () => {
	const tool = getTool('dlv-dap');
	const latestVersion = tool.latestVersion;

	teardown(() => {
		sinon.restore();
	});

	async function testShouldUpdateTool(expected: boolean, moduleVersion?: string) {
		sinon.stub(goInstallTools, 'inspectGoToolVersion').returns(Promise.resolve({ moduleVersion }));
		const got = await goInstallTools.shouldUpdateTool(tool, '/bin/path/to/dlv-dap');
		assert.strictEqual(
			expected,
			got,
			`hard-coded minimum: ${tool.latestVersion.toString()} vs localVersion: ${moduleVersion}`
		);
	}

	test('local delve is old', async () => {
		await testShouldUpdateTool(true, 'v1.6.0');
	});

	test('local delve is the minimum required version', async () => {
		await testShouldUpdateTool(false, 'v' + latestVersion.toString());
	});

	test('local delve is newer', async () => {
		await testShouldUpdateTool(false, `v${latestVersion.major}.${latestVersion.minor + 1}.0`);
	});

	test('local delve is slightly older', async () => {
		await testShouldUpdateTool(
			true,
			`v${latestVersion.major}.${latestVersion.minor}.${latestVersion.patch}-0.20201231000000-5360c6286949`
		);
	});

	test('local delve is slightly newer', async () => {
		await testShouldUpdateTool(
			false,
			`v{$latestVersion.major}.${latestVersion.minor}.${latestVersion.patch}-0.30211231000000-5360c6286949`
		);
	});

	test('local delve version is unknown', async () => {
		// maybe a wrapper shellscript?
		await testShouldUpdateTool(false, undefined);
	});

	test('local delve version is non-sense', async () => {
		// maybe a wrapper shellscript?
		await testShouldUpdateTool(false, 'hello');
	});

	test('local delve version is non-sense again', async () => {
		// maybe a wrapper shellscript?
		await testShouldUpdateTool(false, '');
	});
});
