/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------*/

import AdmZip = require('adm-zip');
import * as assert from 'assert';
import cp = require('child_process');
import fs = require('fs');
import os = require('os');
import path = require('path');
import sinon = require('sinon');
import util = require('util');
import vscode = require('vscode');
import { installTools } from '../../src/goInstallTools';
import { getTool, getToolAtVersion } from '../../src/goTools';
import { getBinPath, getGoVersion, rmdirRecursive } from '../../src/util';

suite('Installation Tests', function () {
	this.timeout(10000);

	test('install tools', async () => {
		const goVersion = await getGoVersion();
		const testCases: string[][] = [
			['gopls'],
			['gopls', 'guru'],
		];
		const proxyDir = buildFakeProxy([].concat(...testCases));

		for (const missing of testCases) {
			// Create a temporary directory in which to install tools.
			const tmpToolsGopath = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test'));
			fs.mkdirSync(path.join(tmpToolsGopath, 'bin'));
			fs.mkdirSync(path.join(tmpToolsGopath, 'src'));

			const sandbox = sinon.createSandbox();
			const utils = require('../../src/util');

			const toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(tmpToolsGopath);
			const goConfig = Object.create(vscode.workspace.getConfiguration('go'), {
				toolsEnvVars: {
					value: {
						GOPROXY: `file://${proxyDir}`,
						GOSUMDB: 'off',
					}
				},
			});
			const configStub = sandbox.stub(vscode.workspace, 'getConfiguration').returns(goConfig);
			// TODO(rstambler): Test with versions as well.
			const missingTools = missing.map((tool) => getToolAtVersion(tool));
			await installTools(missingTools, goVersion);

			sinon.assert.calledWith(toolsGopathStub);
			sinon.assert.calledWith(configStub);
			sandbox.restore();

			// Read the $GOPATH/bin to confirm that the expected tools were
			// installed.
			const readdir = util.promisify(fs.readdir);
			const files = await readdir(path.join(tmpToolsGopath, 'bin'));
			assert.deepEqual(files, missing, `tool installation failed for ${missing}`);

			// Clean up the temporary GOPATH. To delete the module cache, run `go clean -modcache`.
			const goRuntimePath = getBinPath('go');
			const envForTest = Object.assign({}, process.env);
			envForTest['GOPATH'] = tmpToolsGopath;
			const execFile = util.promisify(cp.execFile);
			await execFile(goRuntimePath, ['clean', '-modcache'], {
				env: envForTest,
			});
			rmdirRecursive(tmpToolsGopath);
		}

		rmdirRecursive(proxyDir);
	});
});

// buildFakeProxy creates a fake file-based proxy used for testing. The code is
// mostly adapted from golang.org/x/tools/internal/proxydir/proxydir.go.
function buildFakeProxy(tools: string[]) {
	const proxyDir = fs.mkdtempSync(path.join(os.tmpdir(), 'proxydir'));
	for (const toolName of tools) {
		const tool = getTool(toolName);
		const module = tool.importPath;
		const version = `v1.0.0`; // hardcoded for now
		const dir = path.join(proxyDir, module, '@v');
		fs.mkdirSync(dir, { recursive: true });

		// Write the list file.
		fs.writeFileSync(path.join(dir, 'list'), `${version}\n`);

		// Write the go.mod file.
		fs.writeFileSync(path.join(dir, `${version}.mod`), `module ${module}\n`);

		// Write the info file.
		fs.writeFileSync(path.join(dir, `${version}.info`), `{ "Version": "${version}", "Time": "2020-04-07T14:45:07Z" } `);

		// Write the zip file.
		const zip = new AdmZip();
		const content = `package main; func main() {};`;
		zip.addFile(path.join(`${module}@${version}`, 'main.go'), Buffer.alloc(content.length, content));
		zip.writeZip(path.join(dir, `${version}.zip`));
	}
	return proxyDir;
}
