/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/
import assert = require('assert');
import path = require('path');
import sinon = require('sinon');
import { TextDocument, TestItem, TestItemCollection, TextDocumentChangeEvent, workspace, Uri } from 'vscode';
import { GoTestExplorer } from '../../src/goTest/explore';
import { MockTestController, MockTestWorkspace } from '../mocks/MockTest';
import { forceDidOpenTextDocument, getSymbols_Regex, populateModulePathCache } from './goTest.utils';
import { MockExtensionContext } from '../mocks/MockContext';
import { MockMemento } from '../mocks/MockMemento';
import * as config from '../../src/config';
import { GoTestResolver } from '../../src/goTest/resolve';
import * as testUtils from '../../src/testUtils';
import { GoTest } from '../../src/goTest/utils';
import { Env } from './goplsTestEnv.utils';
import { MockCfg } from '../mocks/MockCfg';

type Files = Record<string, string | { contents: string; language: string }>;

interface TestCase {
	workspace: string[];
	files: Files;
}

function newExplorer<T extends GoTestExplorer>(
	folders: string[],
	files: Files,
	ctor: new (...args: ConstructorParameters<typeof GoTestExplorer>) => T
) {
	const ws = MockTestWorkspace.from(folders, files);
	const ctrl = new MockTestController();
	const expl = new ctor({}, ws, ctrl, new MockMemento(), getSymbols_Regex);
	populateModulePathCache(ws);
	return { ctrl, expl, ws };
}

function assertTestItems(items: TestItemCollection, expect: string[]) {
	const actual: string[] = [];
	function walk(items: TestItemCollection) {
		items.forEach((item) => {
			actual.push(item.id);
			walk(item.children);
		});
	}
	walk(items);
	assert.deepStrictEqual(actual, expect);
}

async function forceResolve(resolver: GoTestResolver, item?: TestItem) {
	await resolver.resolve(item);
	const items: TestItem[] = [];
	(item?.children || resolver.items).forEach((x) => items.push(x));
	await Promise.all(items.map((x) => forceResolve(resolver, x)));
}

suite('Go Test Explorer', () => {
	suite('Document opened', () => {
		class DUT extends GoTestExplorer {
			async _didOpen(doc: TextDocument) {
				await this.didOpenTextDocument(doc);
			}

			async _didCreate(doc: TextDocument) {
				await this.didCreateFile(doc.uri);
			}
		}

		interface TC extends TestCase {
			uri: string;
			expectCreate: string[];
			expectOpen: string[];
		}

		const cases: Record<string, TC> = {
			'In workspace': {
				workspace: ['/src/proj'],
				files: {
					'/src/proj/go.mod': 'module test',
					'/src/proj/foo_test.go': 'package main\nfunc TestFoo(*testing.T) {}',
					'/src/proj/bar_test.go': 'package main\nfunc TestBar(*testing.T) {}',
					'/src/proj/baz/main_test.go': 'package main\nfunc TestBaz(*testing.T) {}'
				},
				uri: 'file:///src/proj/foo_test.go',
				expectCreate: ['file:///src/proj?module', 'file:///src/proj/foo_test.go?file'],
				expectOpen: [
					'file:///src/proj?module',
					'file:///src/proj/foo_test.go?file',
					'file:///src/proj/foo_test.go?test#TestFoo'
				]
			},
			'Outside workspace': {
				workspace: [],
				files: {
					'/src/proj/go.mod': 'module test',
					'/src/proj/foo_test.go': 'package main\nfunc TestFoo(*testing.T) {}'
				},
				uri: 'file:///src/proj/foo_test.go',
				expectCreate: ['file:///src/proj?module', 'file:///src/proj/foo_test.go?file'],
				expectOpen: [
					'file:///src/proj?module',
					'file:///src/proj/foo_test.go?file',
					'file:///src/proj/foo_test.go?test#TestFoo'
				]
			}
		};

		for (const name in cases) {
			test(name, async () => {
				const { workspace, files, uri: uri, expectCreate: expectCreate, expectOpen: expectOpen } = cases[name];
				const { ctrl, expl, ws } = newExplorer(workspace, files, DUT);

				const doc = ws.fs.files.get(uri);
				assert(doc);

				await expl._didCreate(doc);
				assertTestItems(ctrl.items, expectCreate);

				await expl._didOpen(doc);
				assertTestItems(ctrl.items, expectOpen);
			});
		}
	});

	suite('Document edited', async () => {
		class DUT extends GoTestExplorer {
			async _didOpen(doc: TextDocument) {
				await this.didOpenTextDocument(doc);
			}

			async _didChange(e: TextDocumentChangeEvent) {
				await this.didChangeTextDocument(e);
			}
		}

		interface TC extends TestCase {
			open: string;
			changes: [string, string][];
			expect: {
				before: string[];
				after: string[];
			};
		}

		const cases: Record<string, TC> = {
			'Add test': {
				workspace: ['/src/proj'],
				files: {
					'/src/proj/go.mod': 'module test',
					'/src/proj/foo_test.go': 'package main'
				},
				open: 'file:///src/proj/foo_test.go',
				changes: [['file:///src/proj/foo_test.go', 'package main\nfunc TestFoo(*testing.T) {}']],
				expect: {
					before: ['file:///src/proj?module'],
					after: [
						'file:///src/proj?module',
						'file:///src/proj/foo_test.go?file',
						'file:///src/proj/foo_test.go?test#TestFoo'
					]
				}
			},
			'Remove test': {
				workspace: ['/src/proj'],
				files: {
					'/src/proj/go.mod': 'module test',
					'/src/proj/foo_test.go': 'package main\nfunc TestFoo(*testing.T) {}'
				},
				open: 'file:///src/proj/foo_test.go',
				changes: [['file:///src/proj/foo_test.go', 'package main']],
				expect: {
					before: [
						'file:///src/proj?module',
						'file:///src/proj/foo_test.go?file',
						'file:///src/proj/foo_test.go?test#TestFoo'
					],
					after: ['file:///src/proj?module']
				}
			}
		};

		for (const name in cases) {
			test(name, async () => {
				const { workspace, files, open, changes, expect } = cases[name];
				const { ctrl, expl, ws } = newExplorer(workspace, files, DUT);

				const doc = ws.fs.files.get(open);
				assert(doc);
				await expl._didOpen(doc);

				assertTestItems(ctrl.items, expect.before);

				for (const [file, contents] of changes) {
					const doc = ws.fs.files.get(file);
					assert(doc);
					doc.contents = contents;
					await expl._didChange({
						document: doc,
						contentChanges: [],
						reason: undefined
					});
				}

				assertTestItems(ctrl.items, expect.after);
			});
		}
	});

	suite('stretchr', function () {
		// This test suite requires stretcher module so gopls start may take a while.
		const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata', 'stretchrTestSuite');
		const ctx = MockExtensionContext.new();
		let document: TextDocument;
		let testExplorer: GoTestExplorer;

		const env = new Env();

		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');
			ctx.teardown();
		});

		test('discovery', async () => {
			const uri = Uri.file(path.join(fixtureDir, 'suite_test.go'));
			// TODO(hyangah): I don't know why, but gopls seems to pick up ./test/testdata/codelens as
			// the workspace directory when we don't explicitly set the workspace directory
			// (so initialize request doesn't include workspace dir info). The codelens directory was
			// used in the previous test suite. Figure out why.
			await env.startGopls(uri.fsPath, undefined, fixtureDir);

			testExplorer = GoTestExplorer.setup(ctx, env.goCtx);

			document = await forceDidOpenTextDocument(workspace, testExplorer, uri);
			const tests = testExplorer.resolver.find(document.uri).map((x) => x.id);
			assert.deepStrictEqual(tests.sort(), [
				document.uri.with({ query: 'file' }).toString(),
				document.uri.with({ query: 'test', fragment: '(*ExampleTestSuite).TestExample' }).toString(),
				document.uri.with({ query: 'test', fragment: 'TestExampleTestSuite' }).toString()
			]);
		});
	});

	suite('settings', () => {
		const sandbox = sinon.createSandbox();

		setup(() => {});

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

		suite('packageDisplayMode', () => {
			let resolver: GoTestResolver;

			setup(() => {
				const { expl } = newExplorer(
					['/src/proj'],
					{
						'/src/proj/go.mod': 'module test',
						'/src/proj/pkg/main_test.go': 'package main\nfunc TestFoo(t *testing.T) {}',
						'/src/proj/pkg/sub/main_test.go': 'package main\nfunc TestBar(t *testing.T) {}'
					},
					GoTestExplorer
				);
				resolver = expl.resolver;
			});

			test('flat', async () => {
				// Expect:
				// - module
				//   - package pkg
				//   - package pkg/sub
				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.packageDisplayMode').returns('flat');
				await forceResolve(resolver);

				const mod = resolver.items.get('file:///src/proj?module');
				assert(mod, 'Module is missing or is not at the root');

				const pkg = mod.children.get('file:///src/proj/pkg?package');
				assert(pkg, 'Package pkg is missing or not a child of the module');

				const sub = mod.children.get('file:///src/proj/pkg/sub?package');
				assert(sub, 'Package pkg/sub is missing or not a child of the module');
			});

			test('nested', async () => {
				// Expect:
				// - module
				//   - package pkg
				//     - package pkg/sub
				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.packageDisplayMode').returns('nested');
				await forceResolve(resolver);

				const mod = resolver.items.get('file:///src/proj?module');
				assert(mod, 'Module is missing or is not at the root');

				const pkg = mod.children.get('file:///src/proj/pkg?package');
				assert(pkg, 'Package pkg is missing or not a child of the module');

				const sub = pkg.children.get('file:///src/proj/pkg/sub?package');
				assert(sub, 'Package pkg/sub is missing or not a child of package pkg');
			});
		});

		suite('alwaysRunBenchmarks', () => {
			let explorer: GoTestExplorer;
			let runStub: sinon.SinonStub<[testUtils.TestConfig], Promise<boolean>>;

			const expectedTests = [
				'file:///src/proj/pkg/main_test.go?file',
				'file:///src/proj/pkg/main_test.go?test#TestFoo',
				'file:///src/proj/pkg/main_test.go?benchmark#BenchmarkBar'
			];

			setup(() => {
				runStub = sandbox.stub(testUtils, 'goTest');
				runStub.callsFake(() => Promise.resolve(true));

				explorer = newExplorer(
					['/src/proj'],
					{
						'/src/proj/go.mod': 'module test',
						'/src/proj/pkg/main_test.go': `
							package main

							func TestFoo(t *testing.T) {}
							func BenchmarkBar(b *testing.B) {}
						`
					},
					GoTestExplorer
				).expl;
			});

			test('false', async () => {
				// Running the file should only run the test

				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.alwaysRunBenchmarks').returns(false);
				await forceResolve(explorer.resolver);

				const tests = explorer.resolver.find(Uri.parse('file:///src/proj/pkg/main_test.go'));
				assert.deepStrictEqual(
					tests.map((x) => x.id),
					expectedTests
				);

				await explorer.runner.run({
					include: [tests[0]],
					exclude: undefined,
					profile: undefined
				});
				assert.strictEqual(runStub.callCount, 1, 'Expected goTest to be called once');
				assert.deepStrictEqual(runStub.lastCall.args[0].functions, ['TestFoo']);
			});

			test('true', async () => {
				// Running the file should run the test and the benchmark
				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.alwaysRunBenchmarks').returns(true);
				await forceResolve(explorer.resolver);

				const tests = explorer.resolver.find(Uri.parse('file:///src/proj/pkg/main_test.go'));
				assert.deepStrictEqual(
					tests.map((x) => x.id),
					expectedTests
				);

				await explorer.runner.run({
					include: [tests[0]],
					exclude: undefined,
					profile: undefined
				});
				assert.strictEqual(runStub.callCount, 2, 'Expected goTest to be called twice');
				assert.deepStrictEqual(runStub.firstCall.args[0].functions, ['TestFoo']);
				assert.deepStrictEqual(runStub.secondCall.args[0].functions, ['BenchmarkBar']);
			});
		});

		suite('showDynamicSubtestsInEditor', () => {
			let explorer: GoTestExplorer;
			let runStub: sinon.SinonStub<[testUtils.TestConfig], Promise<boolean>>;

			setup(() => {
				runStub = sandbox.stub(testUtils, 'goTest');
				runStub.callsFake((cfg) => {
					// Trigger creation of dynamic subtest
					cfg.goTestOutputConsumer?.({
						Test: 'TestFoo/Bar',
						Action: 'run'
					});
					return Promise.resolve(true);
				});

				explorer = newExplorer(
					['/src/proj'],
					{
						'/src/proj/go.mod': 'module test',
						'/src/proj/main_test.go': 'package main\nfunc TestFoo(t *testing.T) {}'
					},
					GoTestExplorer
				).expl;
			});

			test('false', async () => {
				// Dynamic subtests should have no location
				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.showDynamicSubtestsInEditor').returns(false);
				await forceResolve(explorer.resolver);

				const test = explorer.resolver
					.find(Uri.parse('file:///src/proj/main_test.go'))
					.filter((x) => GoTest.parseId(x.id).name)[0];
				assert(test, 'Could not find test');

				await explorer.runner.run({
					include: [test],
					exclude: undefined,
					profile: undefined
				});
				assert.strictEqual(runStub.callCount, 1, 'Expected goTest to be called once');

				const subTest = test.children.get('file:///src/proj/main_test.go?test#TestFoo%2FBar');
				assert(subTest, 'Could not find subtest');

				assert(!subTest.range, 'Subtest should not have a range');
			});

			test('true', async () => {
				// Dynamic subtests should have the same location as their parents
				const goConfig = new MockCfg([]);
				sandbox.stub(config, 'getGoConfig').returns(goConfig);
				sandbox.stub(goConfig, 'get').withArgs('testExplorer.showDynamicSubtestsInEditor').returns(true);
				await forceResolve(explorer.resolver);

				const test = explorer.resolver
					.find(Uri.parse('file:///src/proj/main_test.go'))
					.filter((x) => GoTest.parseId(x.id).name)[0];
				assert(test, 'Could not find test');

				await explorer.runner.run({
					include: [test],
					exclude: undefined,
					profile: undefined
				});
				assert.strictEqual(runStub.callCount, 1, 'Expected goTest to be called once');

				const subTest = test.children.get('file:///src/proj/main_test.go?test#TestFoo%2FBar');
				assert(subTest, 'Could not find subtest');

				assert.deepStrictEqual(subTest.range, test.range, 'Subtest range should match parent range');
			});
		});
	});
});
