/* eslint-disable no-prototype-builtins */
/* 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 vscode = require('vscode');
import { getGoConfig } from './config';
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
import { byteOffsetAt, getBinPath, getFileArchive } from './util';

// Interface for the output from gomodifytags
interface GomodifytagsOutput {
	start: number;
	end: number;
	lines: string[];
}

// Interface for settings configuration for adding and removing tags
interface GoTagsConfig {
	[key: string]: any;
	tags: string;
	options: string;
	promptForTags: boolean;
	template: string;
}

export function addTags(commandArgs: GoTagsConfig) {
	const args = getCommonArgs();
	if (!args) {
		return;
	}

	getTagsAndOptions(<GoTagsConfig>getGoConfig()['addTags'], commandArgs).then(
		([tags, options, transformValue, template]) => {
			if (!tags && !options) {
				return;
			}
			if (tags) {
				args.push('--add-tags');
				args.push(tags);
			}
			if (options) {
				args.push('--add-options');
				args.push(options);
			}
			if (transformValue) {
				args.push('--transform');
				args.push(transformValue);
			}
			if (template) {
				args.push('--template');
				args.push(template);
			}
			runGomodifytags(args);
		}
	);
}

export function removeTags(commandArgs: GoTagsConfig) {
	const args = getCommonArgs();
	if (!args) {
		return;
	}

	getTagsAndOptions(<GoTagsConfig>getGoConfig()['removeTags'], commandArgs).then(([tags, options]) => {
		if (!tags && !options) {
			args.push('--clear-tags');
			args.push('--clear-options');
		}
		if (tags) {
			args.push('--remove-tags');
			args.push(tags);
		}
		if (options) {
			args.push('--remove-options');
			args.push(options);
		}
		runGomodifytags(args);
	});
}

function getCommonArgs(): string[] {
	const editor = vscode.window.activeTextEditor;
	if (!editor) {
		vscode.window.showInformationMessage('No editor is active.');
		return;
	}
	if (!editor.document.fileName.endsWith('.go')) {
		vscode.window.showInformationMessage('Current file is not a Go file.');
		return;
	}
	const args = ['-modified', '-file', editor.document.fileName, '-format', 'json'];
	if (
		editor.selection.start.line === editor.selection.end.line &&
		editor.selection.start.character === editor.selection.end.character
	) {
		// Add tags to the whole struct
		const offset = byteOffsetAt(editor.document, editor.selection.start);
		args.push('-offset');
		args.push(offset.toString());
	} else if (editor.selection.start.line <= editor.selection.end.line) {
		// Add tags to selected lines
		args.push('-line');
		args.push(`${editor.selection.start.line + 1},${editor.selection.end.line + 1}`);
	}

	return args;
}

function getTagsAndOptions(config: GoTagsConfig, commandArgs: GoTagsConfig): Thenable<string[]> {
	const tags = commandArgs && commandArgs.hasOwnProperty('tags') ? commandArgs['tags'] : config['tags'];
	const options = commandArgs && commandArgs.hasOwnProperty('options') ? commandArgs['options'] : config['options'];
	const promptForTags =
		commandArgs && commandArgs.hasOwnProperty('promptForTags')
			? commandArgs['promptForTags']
			: config['promptForTags'];
	const transformValue: string =
		commandArgs && commandArgs.hasOwnProperty('transform') ? commandArgs['transform'] : config['transform'];
	const format: string =
		commandArgs && commandArgs.hasOwnProperty('template') ? commandArgs['template'] : config['template'];

	if (!promptForTags) {
		return Promise.resolve([tags, options, transformValue, format]);
	}

	return vscode.window
		.showInputBox({
			value: tags,
			prompt: 'Enter comma separated tag names'
		})
		.then((inputTags) => {
			return vscode.window
				.showInputBox({
					value: options,
					prompt: 'Enter comma separated options'
				})
				.then((inputOptions) => {
					return vscode.window
						.showInputBox({
							value: transformValue,
							prompt: 'Enter transform value'
						})
						.then((transformOption) => {
							return vscode.window
								.showInputBox({
									value: format,
									prompt: 'Enter template value'
								})
								.then((template) => {
									return [inputTags, inputOptions, transformOption, template];
								});
						});
				});
		});
}

function runGomodifytags(args: string[]) {
	const gomodifytags = getBinPath('gomodifytags');
	const editor = vscode.window.activeTextEditor;
	const input = getFileArchive(editor.document);
	const p = cp.execFile(gomodifytags, args, { env: toolExecutionEnvironment() }, (err, stdout, stderr) => {
		if (err && (<any>err).code === 'ENOENT') {
			promptForMissingTool('gomodifytags');
			return;
		}
		if (err && (<any>err).code === 2 && args.indexOf('--template') > 0) {
			vscode.window.showInformationMessage(
				'Cannot modify tags: you might be using a' + 'version that does not support --template'
			);
			promptForUpdatingTool('gomodifytags');
			return;
		}
		if (err) {
			vscode.window.showInformationMessage(`Cannot modify tags: ${stderr}`);
			return;
		}
		const output = <GomodifytagsOutput>JSON.parse(stdout);
		vscode.window.activeTextEditor.edit((editBuilder) => {
			editBuilder.replace(new vscode.Range(output.start - 1, 0, output.end, 0), output.lines.join('\n') + '\n');
		});
	});
	if (p.pid) {
		p.stdin.end(input);
	}
}
