/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-prototype-builtins */
import assert = require('assert');
import fs = require('fs');
import os = require('os');
import path = require('path');
import sinon = require('sinon');
import vscode = require('vscode');
import { getGoConfig } from '../../src/config';
import { GoDebugConfigurationProvider } from '../../src/goDebugConfiguration';
import { updateGoVarsFromConfig } from '../../src/goInstallTools';
import { rmdirRecursive } from '../../src/util';
import goEnv = require('../../src/goEnv');
import { isInPreviewMode } from '../../src/goLanguageServer';

suite('Debug Environment Variable Merge Test', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();

	suiteSetup(async () => {
		await updateGoVarsFromConfig();

		// Set up the test fixtures.
		const fixtureSourcePath = path.join(__dirname, '..', '..', '..', 'test', 'testdata');
		const filePath = path.join(fixtureSourcePath, 'baseTest', 'test.go');
		await vscode.workspace.openTextDocument(vscode.Uri.file(filePath));
	});

	suiteTeardown(() => {
		vscode.commands.executeCommand('workbench.action.closeActiveEditor');
	});

	let sandbox: sinon.SinonSandbox;
	let tmpDir = '';
	const toolExecutionEnv: NodeJS.Dict<string> = {};
	setup(() => {
		tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'godebugconfig_test'));
		sandbox = sinon.createSandbox();
	});

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

	interface Input {
		env?: { [key: string]: any };
		envFile?: string | string[];
		toolsEnv?: { [key: string]: any };
	}

	function runTest(input: Input, expected: { [key: string]: any }) {
		sandbox.stub(goEnv, 'toolExecutionEnvironment').returns(input.toolsEnv || {});
		const config = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(undefined, {
			type: 'go',
			name: 'Launch',
			request: 'launch',
			env: input.env,
			envFile: input.envFile
		});

		const actual = config.env;
		assert.deepStrictEqual(actual, expected);
	}

	test('works with empty launchArgs', () => {
		runTest({}, {});
	});

	test('toolsEnvVars is propagated', () => {
		const toolsEnv = {
			GOPATH: '/gopath',
			GOOS: 'valueFromToolsEnv'
		};

		runTest(
			{ toolsEnv },
			{
				GOPATH: '/gopath',
				GOOS: 'valueFromToolsEnv'
			}
		);
	});

	test('preserves settings from launchArgs.env', () => {
		const env = { GOPATH: 'valueFromEnv', GOOS: 'valueFromEnv2' };
		runTest(
			{ env },
			{
				GOPATH: 'valueFromEnv',
				GOOS: 'valueFromEnv2'
			}
		);
	});

	test('preserves settings from launchArgs.envFile', () => {
		const envFile = path.join(tmpDir, 'env');
		fs.writeFileSync(envFile, 'GOPATH=valueFromEnvFile');
		runTest({ envFile }, { GOPATH: 'valueFromEnvFile' });
	});

	test('launchArgs.env overwrites launchArgs.envFile', () => {
		const env = { SOMEVAR1: 'valueFromEnv' };
		const envFile = path.join(tmpDir, 'env');
		fs.writeFileSync(envFile, ['SOMEVAR1=valueFromEnvFile1', 'SOMEVAR2=valueFromEnvFile2'].join('\n'));

		runTest(
			{ env, envFile },
			{
				SOMEVAR1: 'valueFromEnv',
				SOMEVAR2: 'valueFromEnvFile2'
			}
		);
	});

	test('launchArgs.env overwrites toolsEnvVar', () => {
		const toolsEnv = {
			GOPATH: '/gopath',
			SOMEVAR1: 'valueFromToolsEnvVar1',
			SOMEVAR2: 'valueFromToolsEnvVar2'
		};

		const env = { SOMEVAR1: 'valueFromEnv' };
		runTest(
			{ env, toolsEnv },
			{
				GOPATH: '/gopath',
				SOMEVAR1: 'valueFromEnv',
				SOMEVAR2: 'valueFromToolsEnvVar2'
			}
		);
	});

	test('launchArgs.envFile overwrites toolsEnvVar', () => {
		const toolsEnv = {
			GOPATH: '/gopath',
			SOMEVAR1: 'valueFromToolsEnvVar1',
			SOMEVAR2: 'valueFromToolsEnvVar2'
		};
		const envFile = path.join(tmpDir, 'env');
		fs.writeFileSync(envFile, ['SOMEVAR2=valueFromEnvFile2'].join('\n'));

		runTest(
			{ toolsEnv, envFile },
			{
				GOPATH: '/gopath',
				SOMEVAR1: 'valueFromToolsEnvVar1',
				SOMEVAR2: 'valueFromEnvFile2'
			}
		);
	});
});

suite('Debug Configuration Merge User Settings', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();
	const config = require('../../src/config');

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

	suite("merge 'go' config from settings.json", () => {
		test('go flags config does not affect debug config', async () => {
			// This tests that the testFlags and GOOS and GOARCH set
			// in settings.json do not affect the resolved debug configuration.
			// When this expected behavior changes, this test can be updated.

			// Run resolveDebugConfiguration with the default workspace settings.
			const cfg1 = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}'
			};

			const emptyResult = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg1);
			const goConfig = Object.create(getGoConfig(), {
				testFlags: { value: '-tags=myTagTest' },
				buildFlags: { value: '-tags=myTagBuild' },
				goroot: { value: '/path/to/goroot' },
				gopath: { value: '/path/to/gopath' }
			}) as vscode.WorkspaceConfiguration;

			// Adjust the workspace config.
			sinon.stub(config, 'getGoConfig').returns(goConfig);

			const cfg2 = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}'
			};

			const filledResult = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg2);

			assert.strictEqual(filledResult.name, emptyResult.name);
			assert.strictEqual(filledResult.type, emptyResult.type);
			assert.strictEqual(filledResult.mode, emptyResult.mode);
			assert.strictEqual(filledResult.request, emptyResult.request);
			assert.strictEqual(filledResult.program, emptyResult.program);
			assert.strictEqual(filledResult.dlvToolPath, emptyResult.dlvToolPath);
			assert.strictEqual(filledResult.apiVersion, emptyResult.apiVersion);
			assert.strictEqual(filledResult.showGlobalVariables, emptyResult.showGlobalVariables);
			assert.strictEqual(filledResult.debugAdapter, emptyResult.debugAdapter);
			assert.strictEqual(filledResult.substitutePath, emptyResult.substitutePath);
		});

		test('delve config in settings.json is added to debug config', async () => {
			// This tests that the testFlags and GOOS and GOARCH set
			// in settings.json do not affect the resolved debug configuration.
			// When this expected behavior changes, this test can be updated.

			// Run resolveDebugConfiguration with the default workspace settings.
			const goConfig = Object.create(getGoConfig(), {
				delveConfig: {
					value: {
						dlvLoadConfig: {
							followPointers: false,
							maxVariableRecurse: 3,
							maxStringLen: 32,
							maxArrayValues: 32,
							maxStructFields: 5
						},
						apiVersion: 1,
						showGlobalVariables: true,
						debugAdapter: 'dlv-dap',
						substitutePath: [{ from: 'hello', to: 'goodbye' }]
					}
				}
			}) as vscode.WorkspaceConfiguration;
			sinon.stub(config, 'getGoConfig').returns(goConfig);

			const cfg = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}'
			};

			const result = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg);
			assert.strictEqual(result.apiVersion, 1);
			assert.strictEqual(result.showGlobalVariables, true);
			assert.strictEqual(result.debugAdapter, 'dlv-dap');
			assert.strictEqual(result.substitutePath.length, 1);
			assert.strictEqual(result.substitutePath[0].from, 'hello');
			assert.strictEqual(result.substitutePath[0].to, 'goodbye');
			const dlvLoadConfig = result.dlvLoadConfig;
			assert.strictEqual(dlvLoadConfig.followPointers, false);
			assert.strictEqual(dlvLoadConfig.maxVariableRecurse, 3);
			assert.strictEqual(dlvLoadConfig.maxStringLen, 32);
			assert.strictEqual(dlvLoadConfig.maxArrayValues, 32);
			assert.strictEqual(dlvLoadConfig.maxStructFields, 5);
		});

		test('delve config in settings.json is overriden by launch.json', async () => {
			// This tests that the testFlags and GOOS and GOARCH set
			// in settings.json do not affect the resolved debug configuration.
			// When this expected behavior changes, this test can be updated.

			// Run resolveDebugConfiguration with the default workspace settings.
			const goConfig = Object.create(getGoConfig(), {
				delveConfig: {
					value: {
						dlvLoadConfig: {
							followPointers: false,
							maxVariableRecurse: 3,
							maxStringLen: 32,
							maxArrayValues: 32,
							maxStructFields: 5
						},
						apiVersion: 1,
						showGlobalVariables: true,
						debugAdapter: 'dlv-dap',
						substitutePath: [{ from: 'hello', to: 'goodbye' }]
					}
				}
			}) as vscode.WorkspaceConfiguration;
			sinon.stub(config, 'getGoConfig').returns(goConfig);

			const cfg: vscode.DebugConfiguration = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}',
				apiVersion: 2,
				showGlobalVariables: false,
				dlvLoadConfig: {
					followPointers: true,
					maxVariableRecurse: 6,
					maxStringLen: 128,
					maxArrayValues: 128,
					maxStructFields: -1
				},
				debugAdapter: 'legacy',
				substitutePath: []
			};

			const result = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg);
			assert.strictEqual(result.apiVersion, 2);
			assert.strictEqual(result.showGlobalVariables, false);
			assert.strictEqual(result.debugAdapter, 'legacy');
			assert.strictEqual(result.substitutePath.length, 0);
			const dlvLoadConfig = result.dlvLoadConfig;
			assert.strictEqual(dlvLoadConfig.followPointers, true);
			assert.strictEqual(dlvLoadConfig.maxVariableRecurse, 6);
			assert.strictEqual(dlvLoadConfig.maxStringLen, 128);
			assert.strictEqual(dlvLoadConfig.maxArrayValues, 128);
			assert.strictEqual(dlvLoadConfig.maxStructFields, -1);
		});
	});
});

suite('Debug Configuration Modify User Config', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();

	suite('remove gcflags', () => {
		test('remove gcflags from string args', () => {
			const tt = [
				{
					input: '-gcflags=all=-l',
					want: { args: '', removed: true }
				},
				{
					input: '-gcflags all=-l',
					want: { args: '', removed: true }
				},
				// Preserve other flags
				{
					input: '-race -gcflags=all=-l -mod=mod',
					want: { args: '-race -mod=mod', removed: true }
				},
				{
					input: '-race -gcflags all=-l -mod=mod',
					want: { args: '-race -mod=mod', removed: true }
				},
				// Test with quoted value
				{
					input: "-mod=mod -gcflags=test/...='hello goodbye' -race",
					want: { args: '-mod=mod -race', removed: true }
				},
				{
					input: '-mod=mod -gcflags test/...="hello goodbye" -race',
					want: { args: '-mod=mod -race', removed: true }
				},
				{
					input: "-mod=mod -gcflags='test/...=hello goodbye' -race",
					want: { args: '-mod=mod -race', removed: true }
				},
				{
					input: '-mod=mod -gcflags "test/...=hello goodbye" -race',
					want: { args: '-mod=mod -race', removed: true }
				},
				// Multiple -gcflags present
				{
					input: '-mod=mod -gcflags "test/...=hello goodbye" -race -gcflags=all="hello goodbye"',
					want: { args: '-mod=mod -race', removed: true }
				},
				// No gcflags are present
				{
					input: '',
					want: { args: '', removed: false }
				},
				{
					input: '-race -mod=gcflags',
					want: { args: '-race -mod=gcflags', removed: false }
				}
			];

			tt.forEach((tc) => {
				const got = debugConfigProvider.removeGcflags(tc.input);

				assert.strictEqual(got.args, tc.want.args, `args for ${tc.input} do not match expected`);
				assert.strictEqual(got.removed, tc.want.removed, `removed for ${tc.input} does not match expected`);
			});
		});
		test('remove user set -gcflags in buildFlags', () => {
			const config = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}',
				env: {},
				buildFlags: '-race -gcflags=-l -mod=mod'
			};

			debugConfigProvider.resolveDebugConfiguration(undefined, config);
			assert.strictEqual(config.buildFlags, '-race -mod=mod');
		});
		test('remove user set -gcflags in GOFLAGS', () => {
			const config = {
				name: 'Launch',
				type: 'go',
				request: 'launch',
				mode: 'auto',
				program: '${fileDirname}',
				env: { GOFLAGS: '-race -gcflags=-l -mod=mod' }
			};

			debugConfigProvider.resolveDebugConfiguration(undefined, config);

			assert.strictEqual(config.env.GOFLAGS, '-race -mod=mod');
		});
	});
});

suite('Debug Configuration Resolve Paths', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();
	test('resolve ~ in cwd', () => {
		const config = {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			program: '${fileDirname}',
			cwd: '~/main.go'
		};

		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		assert.notStrictEqual(config.cwd, '~/main.go');
	});

	test('do not resolve workspaceFolder or fileDirname', () => {
		const config = {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			program: '${fileDirname}',
			cwd: '${workspaceFolder}'
		};

		debugConfigProvider.resolveDebugConfiguration(undefined, config);

		assert.strictEqual(config.cwd, '${workspaceFolder}');
		assert.strictEqual(config.program, '${fileDirname}');
	});
});

suite('Debug Configuration Converts Relative Paths', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();

	function debugConfig(adapter: string) {
		return {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			debugAdapter: adapter,
			program: path.join('foo', 'bar.go'),
			cwd: '.',
			output: 'debug'
		};
	}

	test('resolve relative paths with workspace root in dlv-dap mode', () => {
		const config = debugConfig('dlv-dap');
		const workspaceFolder = {
			uri: vscode.Uri.file(os.tmpdir()),
			name: 'test',
			index: 0
		};
		const { program, cwd, output } = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(
			workspaceFolder,
			config
		);
		assert.deepStrictEqual(
			{ program, cwd, output },
			{
				program: path.join(os.tmpdir(), 'foo/bar.go'),
				cwd: os.tmpdir(),
				output: path.join(os.tmpdir(), 'debug')
			}
		);
	});

	test('empty, undefined paths are not affected', () => {
		const config = debugConfig('dlv-dap');
		config.program = undefined;
		config.cwd = '';
		delete config.output;

		const workspaceFolder = {
			uri: vscode.Uri.file(os.tmpdir()),
			name: 'test',
			index: 0
		};
		const { program, cwd, output } = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(
			workspaceFolder,
			config
		);
		assert.deepStrictEqual(
			{ program, cwd, output },
			{
				program: undefined,
				cwd: '',
				output: undefined
			}
		);
	});

	test('disallow relative paths with no workspace root', () => {
		const config = debugConfig('dlv-dap');
		const got = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(undefined, config);
		assert.strictEqual(got, null);
	});

	test('do not affect relative paths (workspace) in legacy mode', () => {
		const config = debugConfig('legacy');
		const workspaceFolder = {
			uri: vscode.Uri.file(os.tmpdir()),
			name: 'test',
			index: 0
		};
		const { program, cwd, output } = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(
			workspaceFolder,
			config
		);
		assert.deepStrictEqual(
			{ program, cwd, output },
			{
				program: path.join('foo', 'bar.go'),
				cwd: '.',
				output: 'debug'
			}
		);
	});

	test('do not affect relative paths (no workspace) in legacy mode', () => {
		const config = debugConfig('legacy');
		const { program, cwd, output } = debugConfigProvider.resolveDebugConfigurationWithSubstitutedVariables(
			undefined,
			config
		);
		assert.deepStrictEqual(
			{ program, cwd, output },
			{
				program: path.join('foo', 'bar.go'),
				cwd: '.',
				output: 'debug'
			}
		);
	});
});

suite('Debug Configuration Auto Mode', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();
	test('resolve auto to debug with non-test file', () => {
		const config = {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			program: '/path/to/main.go'
		};

		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		assert.strictEqual(config.mode, 'debug');
		assert.strictEqual(config.program, '/path/to/main.go');
	});

	test('resolve auto to debug with test file', () => {
		const config = {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			program: '/path/to/main_test.go'
		};

		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		assert.strictEqual(config.mode, 'test');
		assert.strictEqual(config.program, '/path/to');
	});
});

suite('Debug Configuration Default DebugAdapter', () => {
	const debugConfigProvider = new GoDebugConfigurationProvider();
	test(`default debugAdapter when isInPreviewMode=${isInPreviewMode()} should be 'dlv-dap'`, () => {
		const config = {
			name: 'Launch',
			type: 'go',
			request: 'launch',
			mode: 'auto',
			program: '/path/to/main.go'
		};

		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		const resolvedConfig = config as any;
		const want = isInPreviewMode() ? 'dlv-dap' : 'legacy';
		assert.strictEqual(resolvedConfig['debugAdapter'], want);
	});

	test("default debugAdapter for remote mode should be always 'legacy'", () => {
		const config = {
			name: 'Attach',
			type: 'go',
			request: 'attach',
			mode: 'remote',
			program: '/path/to/main_test.go',
			cwd: '/path'
		};

		const want = 'legacy'; // remote mode works only with legacy mode.
		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		const resolvedConfig = config as any;
		assert.strictEqual(resolvedConfig['debugAdapter'], want);
	});

	test('debugAdapter=dlv-dap should be ignored for remote mode', () => {
		const config = {
			name: 'Attach',
			type: 'go',
			request: 'attach',
			mode: 'remote',
			debugAdapter: 'dlv-dap',
			program: '/path/to/main_test.go',
			cwd: '/path'
		};

		const want = 'legacy'; // remote mode works only with legacy mode.
		debugConfigProvider.resolveDebugConfiguration(undefined, config);
		const resolvedConfig = config as any;
		assert.strictEqual(resolvedConfig['debugAdapter'], want);
	});
});
