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

import path = require('path');
import vscode = require('vscode');
import { buildDiagnosticCollection } from './goMain';
import { isModSupported } from './goModules';
import { getNonVendorPackages } from './goPackages';
import { getCurrentGoWorkspaceFromGOPATH } from './goPath';
import { diagnosticsStatusBarItem, outputChannel } from './goStatus';
import { getTestFlags } from './testUtils';
import {
	getCurrentGoPath,
	getGoConfig,
	getModuleCache,
	getTempFilePath,
	getToolsEnvVars,
	getWorkspaceFolderPath,
	handleDiagnosticErrors,
	ICheckResult,
	runTool
} from './util';
/**
 * Builds current package or workspace.
 */
export function buildCode(buildWorkspace?: boolean) {
	const editor = vscode.window.activeTextEditor;
	if (!buildWorkspace) {
		if (!editor) {
			vscode.window.showInformationMessage('No editor is active, cannot find current package to build');
			return;
		}
		if (editor.document.languageId !== 'go') {
			vscode.window.showInformationMessage(
				'File in the active editor is not a Go file, cannot find current package to build'
			);
			return;
		}
	}

	const documentUri = editor ? editor.document.uri : null;
	const goConfig = getGoConfig(documentUri);

	outputChannel.clear(); // Ensures stale output from build on save is cleared
	diagnosticsStatusBarItem.show();
	diagnosticsStatusBarItem.text = 'Building...';

	isModSupported(documentUri).then((isMod) => {
		goBuild(documentUri, isMod, goConfig, buildWorkspace)
			.then((errors) => {
				handleDiagnosticErrors(editor ? editor.document : null, errors, buildDiagnosticCollection);
				diagnosticsStatusBarItem.hide();
			})
			.catch((err) => {
				vscode.window.showInformationMessage('Error: ' + err);
				diagnosticsStatusBarItem.text = 'Build Failed';
			});
	});
}

/**
 * Runs go build -i or go test -i and presents the output in the 'Go' channel and in the diagnostic collections.
 *
 * @param fileUri Document uri.
 * @param isMod Boolean denoting if modules are being used.
 * @param goConfig Configuration for the Go extension.
 * @param buildWorkspace If true builds code in all workspace.
 */
export async function goBuild(
	fileUri: vscode.Uri,
	isMod: boolean,
	goConfig: vscode.WorkspaceConfiguration,
	buildWorkspace?: boolean
): Promise<ICheckResult[]> {
	epoch++;
	const closureEpoch = epoch;
	if (tokenSource) {
		if (running) {
			tokenSource.cancel();
		}
		tokenSource.dispose();
	}
	tokenSource = new vscode.CancellationTokenSource();
	const updateRunning = () => {
		if (closureEpoch === epoch) {
			running = false;
		}
	};

	const currentWorkspace = getWorkspaceFolderPath(fileUri);
	const cwd = buildWorkspace && currentWorkspace ? currentWorkspace : path.dirname(fileUri.fsPath);
	if (!path.isAbsolute(cwd)) {
		return Promise.resolve([]);
	}

	// Skip building if cwd is in the module cache
	if (isMod && cwd.startsWith(getModuleCache())) {
		return [];
	}

	const buildEnv = Object.assign({}, getToolsEnvVars());
	const tmpPath = getTempFilePath('go-code-check');
	const isTestFile = fileUri && fileUri.fsPath.endsWith('_test.go');
	const buildFlags: string[] = isTestFile
		? getTestFlags(goConfig)
		: Array.isArray(goConfig['buildFlags'])
		? [...goConfig['buildFlags']]
		: [];
	const buildArgs: string[] = isTestFile ? ['test', '-c'] : ['build'];

	if (goConfig['installDependenciesWhenBuilding'] === true && !isMod) {
		buildArgs.push('-i');
		// Remove the -i flag from user as we add it anyway
		if (buildFlags.indexOf('-i') > -1) {
			buildFlags.splice(buildFlags.indexOf('-i'), 1);
		}
	}
	buildArgs.push(...buildFlags);
	if (goConfig['buildTags'] && buildFlags.indexOf('-tags') === -1) {
		buildArgs.push('-tags');
		buildArgs.push(goConfig['buildTags']);
	}

	if (buildWorkspace && currentWorkspace && !isTestFile) {
		outputChannel.appendLine(`Starting building the current workspace at ${currentWorkspace}`);
		return getNonVendorPackages(currentWorkspace).then((pkgs) => {
			running = true;
			return runTool(
				buildArgs.concat(Array.from(pkgs.keys())),
				currentWorkspace,
				'error',
				true,
				null,
				buildEnv,
				true,
				tokenSource.token
			).then((v) => {
				updateRunning();
				return v;
			});
		});
	}

	outputChannel.appendLine(`Starting building the current package at ${cwd}`);

	// Find the right importPath instead of directly using `.`. Fixes https://github.com/Microsoft/vscode-go/issues/846
	const currentGoWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), cwd);
	let importPath = '.';
	if (currentGoWorkspace && !isMod) {
		importPath = cwd.substr(currentGoWorkspace.length + 1);
	} else {
		outputChannel.appendLine(
			`Not able to determine import path of current package by using cwd: ${cwd} and Go workspace: ${currentGoWorkspace}`
		);
	}

	running = true;
	return runTool(
		buildArgs.concat('-o', tmpPath, importPath),
		cwd,
		'error',
		true,
		null,
		buildEnv,
		true,
		tokenSource.token
	).then((v) => {
		updateRunning();
		return v;
	});
}

let epoch = 0;
let tokenSource: vscode.CancellationTokenSource;
let running = false;
