/* 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);
	}
}
