/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable eqeqeq */
/* eslint-disable @typescript-eslint/no-explicit-any */
/*---------------------------------------------------------
 * Copyright (C) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/

'use strict';

import cp = require('child_process');
import path = require('path');
import vscode = require('vscode');
import { getGoConfig } from './config';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { buildDiagnosticCollection } from './goMain';
import { isModSupported } from './goModules';
import { getBinPath } from './util';

// Interface for settings configuration for adding and removing tags
interface GoLiveErrorsConfig {
	delay: number;
	enabled: boolean;
}

let runner: NodeJS.Timer;

export function goLiveErrorsEnabled() {
	const goConfig = getGoConfig();
	// If the language server is enabled, there is no need for live errors.
	if (goConfig['useLanguageServer'] === true) {
		return false;
	}
	const liveErrorsConfig = <GoLiveErrorsConfig>goConfig['liveErrors'];
	if (liveErrorsConfig === null || liveErrorsConfig === undefined || !liveErrorsConfig.enabled) {
		return false;
	}
	const files = vscode.workspace.getConfiguration('files', null);
	const autoSave = files['autoSave'];
	const autoSaveDelay = files['autoSaveDelay'];
	if (
		autoSave !== null &&
		autoSave !== undefined &&
		autoSave === 'afterDelay' &&
		autoSaveDelay < liveErrorsConfig.delay * 1.5
	) {
		return false;
	}
	return liveErrorsConfig.enabled;
}

// parseLiveFile runs the gotype command in live mode to check for any syntactic or
// semantic errors and reports them immediately
export function parseLiveFile(e: vscode.TextDocumentChangeEvent) {
	if (e.document.isUntitled) {
		return;
	}
	if (e.document.languageId !== 'go') {
		return;
	}
	if (!goLiveErrorsEnabled()) {
		return;
	}

	if (runner != null) {
		clearTimeout(runner);
	}
	runner = setTimeout(() => {
		processFile(e);
		runner = null;
	}, getGoConfig(e.document.uri)['liveErrors']['delay']);
}

// processFile does the actual work once the timeout has fired
async function processFile(e: vscode.TextDocumentChangeEvent) {
	const isMod = await isModSupported(e.document.uri);
	if (isMod) {
		return;
	}

	const gotypeLive = getBinPath('gotype-live');
	if (!path.isAbsolute(gotypeLive)) {
		return promptForMissingTool('gotype-live');
	}

	const fileContents = e.document.getText();
	const fileName = e.document.fileName;
	const args = ['-e', '-a', '-lf=' + fileName, path.dirname(fileName)];
	const env = toolExecutionEnvironment();
	const p = cp.execFile(gotypeLive, args, { env }, (err, stdout, stderr) => {
		if (err && (<any>err).code === 'ENOENT') {
			promptForMissingTool('gotype-live');
			return;
		}

		buildDiagnosticCollection.clear();

		if (err) {
			// we want to take the error path here because the command we are calling
			// returns a non-zero exit status if the checks fail
			const diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();

			stderr.split('\n').forEach((error) => {
				if (error === null || error.length === 0) {
					return;
				}
				// extract the line, column and error message from the gotype output
				const [_, file, line, column, message] = /^(.+):(\d+):(\d+):\s+(.+)/.exec(error);
				// get canonical file path
				const canonicalFilePath = vscode.Uri.file(file).toString();
				const range = new vscode.Range(+line - 1, +column, +line - 1, +column);
				const diagnostic = new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Error);
				diagnostic.source = 'go';

				const diagnostics = diagnosticMap.get(canonicalFilePath) || [];
				diagnostics.push(diagnostic);
				diagnosticMap.set(canonicalFilePath, diagnostics);
			});

			diagnosticMap.forEach((diagnostics, file) => {
				buildDiagnosticCollection.set(vscode.Uri.parse(file), diagnostics);
			});
		}
	});
	if (p.pid) {
		p.stdin.end(fileContents);
	}
}
