/*---------------------------------------------------------
 * Copyright 2022 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import assert from 'assert';
import path = require('path');
import sinon = require('sinon');
import vscode = require('vscode');
import { ProgressTerminal } from '../../src/progressTerminal';
import { ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';
import { Env, FakeOutputChannel } from './goplsTestEnv.utils';
import { URI } from 'vscode-uri';
import { getGoConfig } from '../../src/config';

suite('writeVulns', function () {
	this.timeout(30000);
	const sandbox = sinon.createSandbox(); // for suite
	const env = new Env();

	// This test suite will start an editor that opens a go workspace in test/testdata/vuln
	// that includes mod1 (that has some vulnerabilities) and mod2 (that has 0 dependency).
	// By reusing the editor session, we reduce the test time by 1.5~2 seconds for each test.
	const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata', 'vuln');

	// Tests will run govulncheck and see if expected output is accumulated in fakeTerminal.
	const fakeTerminal = new FakeOutputChannel();
	suiteSetup(async () => {
		const config = require('../../src/config');
		const goConfig = Object.create(getGoConfig(), {
			// User the GOVULNDB that contains two OSV entries on golang.org/x/text and stdlib modules.
			toolsEnvVars: { value: { GOVULNDB: URI.file(path.join(fixtureDir, 'vulndb')).toString() } }
		}) as vscode.WorkspaceConfiguration;

		sandbox.stub(config, 'getGoConfig').returns(goConfig);
		await env.startGopls(undefined, goConfig, fixtureDir);

		sandbox.stub(ProgressTerminal, 'Open').returns({
			appendLine: fakeTerminal.appendLine,
			show: () => {},
			exit: () => {}
		});
	});

	this.afterEach(async function () {
		if (this.currentTest?.state === 'failed') {
			console.log('=== Gopls Trace ===');
			env.flushTrace(true);
			console.log('=== Vulncheck Terminal Output ===');
			console.log(fakeTerminal.toString());
		}
		env.flushTrace(false);
		fakeTerminal.clear();
	});

	suiteTeardown(async () => {
		await env.teardown();
		sandbox.restore();
	});

	test('govulncheck finds vulnerabilities', async () => {
		const workspaceDir = path.join(fixtureDir, 'mod1');
		const output = await testRunGovulncheck(workspaceDir);
		const result = output.toString();
		assert(result.includes('GO-1970-TEXT'));
		assert(result.includes('vulnerabilities found'));
	});

	test('govulncheck finds no vulnerabilities', async () => {
		const workspaceDir = path.join(fixtureDir, 'mod2');
		const output = await testRunGovulncheck(workspaceDir);
		assert(output.toString().includes('No vulnerabilities found'));
	});

	async function testRunGovulncheck(workspaceDir: string) {
		const languageClient = env.languageClient!;
		const document = await vscode.workspace.openTextDocument(vscode.Uri.file(path.join(workspaceDir, 'go.mod')));
		const uri = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;

		languageClient.middleware!.executeCommand!('gopls.run_govulncheck', [{ URI: uri }], async (cmd, args) => {
			const params: ExecuteCommandParams = {
				command: cmd,
				arguments: args
			};
			return await languageClient?.sendRequest(ExecuteCommandRequest.type, params);
		});
		const msg = 'vulnerabilities found';
		const timeoutMS = 10000;
		await new Promise<void>((resolve, reject) => {
			const timeout = setTimeout(() => {
				reject(`Timed out while waiting for '${msg}'`);
			}, timeoutMS);
			fakeTerminal.onPattern(msg, () => {
				clearTimeout(timeout);
				resolve();
			});
		});
		return fakeTerminal;
	}
});
