/*---------------------------------------------------------
 * 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 { VulncheckTerminal } from '../../src/goVulncheck';
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(VulncheckTerminal, '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 sections = output.toString().split(' Informational ');
		assert(sections.length >= 2, `got ${JSON.stringify(sections)}`);
		assert(sections[0].includes('GO-1970-TEXT'));
		assert(sections[1].includes('GO-1970-FMT'));
		assert(sections[1].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 = 'Share feedback';
		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;
	}
});
