/*---------------------------------------------------------
 * Copyright 2023 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/

import * as vscode from 'vscode';

import { createHash } from 'crypto';
import { ExecuteCommandRequest } from 'vscode-languageserver-protocol';
import { daysBetween } from './goSurvey';
import { LanguageClient } from 'vscode-languageclient/node';
import * as cp from 'child_process';
import { getWorkspaceFolderPath } from './util';
import { toolExecutionEnvironment } from './goEnv';

/**
 * Name of the prompt telemetry command. This is also used to determine if the
 * gopls instance supports telemetry.
 * Exported for testing.
 */
export const GOPLS_MAYBE_PROMPT_FOR_TELEMETRY = 'gopls.maybe_prompt_for_telemetry';

/**
 * Key for the global state that holds the very first time the telemetry-enabled
 * gopls was observed.
 * Exported for testing.
 */
export const TELEMETRY_START_TIME_KEY = 'telemetryStartTime';

/**
 * Run our encode/decode function for the Date object, to be defensive from
 * vscode Memento API behavior change.
 * Exported for testing.
 */
export function recordTelemetryStartTime(storage: vscode.Memento, date: Date) {
	storage.update(TELEMETRY_START_TIME_KEY, date.toJSON());
}

/**
 * TelemetryKey represents the different types of telemetry events.
 */
export enum TelemetryKey {
	// Indicates the installation of vscgo binary.
	VSCGO_INSTALL = 'vscgo_install',
	VSCGO_INSTALL_FAIL = 'vscgo_install_fail',

	// Indicates the activation latency.
	ACTIVATION_LATENCY_L_100MS = 'activation_latency:<100ms',
	ACTIVATION_LATENCY_L_500MS = 'activation_latency:<500ms',
	ACTIVATION_LATENCY_L_1000MS = 'activation_latency:<1000ms',
	ACTIVATION_LATENCY_L_5000MS = 'activation_latency:<5000ms',
	ACTIVATION_LATENCY_GE_5S = 'activation_latency:>=5s',

	// Indicates the tools usage.
	TOOL_USAGE_GOTESTS = 'vscode-go/tool/usage:gotests',
	TOOL_USAGE_GOPLAY = 'vscode-go/tool/usage:goplay',

	// Indicates the command and the source of trigger.
	// The bucket have two elements, the command and it's trigger source.
	COMMAND_TRIGGER_GOPLS_ADD_TEST_COMMAND_PALETTE = 'vscode-go/command/trigger:gopls.add_test-command_palette',
	COMMAND_TRIGGER_GOPLS_ADD_TEST_CONTEXT_MENU = 'vscode-go/command/trigger:gopls.add_test-context_menu',
	COMMAND_TRIGGER_GOPLS_ADD_TEST_CODE_ACTION = 'vscode-go/command/trigger:gopls.add_test-code_action',

	COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_COMMAND_PALETTE = 'vscode-go/command/trigger:gopls.modify_tags-command_palette',
	COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CONTEXT_MENU = 'vscode-go/command/trigger:gopls.modify_tags-context_menu',
	COMMAND_TRIGGER_GOPLS_MODIFY_TAGS_CODE_ACTION = 'vscode-go/command/trigger:gopls.modify_tags-code_action',

	COMMAND_TRIGGER_GOPLS_IMPLEMENT_INTERFACE_COMMAND_PALETTE = 'vscode-go/command/trigger:gopls.implement_interface-command_palette',
	COMMAND_TRIGGER_GOPLS_IMPLEMENT_INTERFACE_CONTEXT_MENU = 'vscode-go/command/trigger:gopls.implement_interface-context_menu',
	COMMAND_TRIGGER_GOPLS_IMPLEMENT_INTERFACE_CODE_ACTION = 'vscode-go/command/trigger:gopls.implement_interface-code_action',

	COMMAND_TRIGGER_GOTESTS_COMMAND_PALETTE = 'vscode-go/command/trigger:gotests-command_palette',
	COMMAND_TRIGGER_GOTESTS_CONTEXT_MENU = 'vscode-go/command/trigger:gotests-context_menu',

	COMMAND_TRIGGER_GOMODIFYTAGS_COMMAND_PALETTE = 'vscode-go/command/trigger:gomodifytags-command_palette',
	COMMAND_TRIGGER_GOMODIFYTAGS_CONTEXT_MENU = 'vscode-go/command/trigger:gomodifytags-context_menu',

	COMMAND_TRIGGER_IMPL_COMMAND_PALETTE = 'vscode-go/command/trigger:impl-command_palette',
	COMMAND_TRIGGER_IMPL_CONTEXT_MENU = 'vscode-go/command/trigger:impl-context_menu'
}

/**
 * Categorizes a duration into a specific latency bucket.
 *
 * @param duration The duration in milliseconds.
 * @returns The TelemetryKey representing the latency bucket.
 */
export function activationLatency(duration: number): TelemetryKey {
	if (duration < 100) {
		return TelemetryKey.ACTIVATION_LATENCY_L_100MS;
	} else if (duration < 500) {
		return TelemetryKey.ACTIVATION_LATENCY_L_500MS;
	} else if (duration < 1000) {
		return TelemetryKey.ACTIVATION_LATENCY_L_1000MS;
	} else if (duration < 5000) {
		return TelemetryKey.ACTIVATION_LATENCY_L_5000MS;
	}
	return TelemetryKey.ACTIVATION_LATENCY_GE_5S;
}

function readTelemetryStartTime(storage: vscode.Memento): Date | null {
	const value = storage.get<string | number | Date>(TELEMETRY_START_TIME_KEY);
	if (!value) {
		return null;
	}
	const telemetryStartTime = new Date(value);
	if (telemetryStartTime.toString() === 'Invalid Date') {
		return null;
	}
	return telemetryStartTime;
}

enum ReporterState {
	NOT_INITIALIZED,
	IDLE,
	RUNNING
}

/**
 * Manages Go telemetry data and persists them to disk using a storage tool.
 *
 * **Usage:**
 * 1. Call `setTool(tool)` once, before any other methods.
 * 2. Call `add(key, value)` to add values associated with keys.
 * 3. Data is automatically flushed to disk periodically.
 * 4. To force an immediate flush, call `flush(true)`.
 *
 * **Example:**
 * ```typescript
 * const r = new TelemetryReporter();
 * r.setTool(vscgo);
 * r.add("count", 10);
 * r.add("count", 5);
 * r.flush(true); // Force a flush
 * ```
 *
 * Exported for testing.
 */
export class TelemetryReporter implements vscode.Disposable {
	private _state = ReporterState.NOT_INITIALIZED;
	private _counters: { [key: string]: number } = {};
	private _flushTimer: NodeJS.Timeout | undefined;
	private _tool = '';

	/**
	 * @param flushIntervalMs is the interval (in milliseconds) between periodic
	 * `flush()` calls.
	 * @param counterFile is the file path for writing telemetry data (used for
	 * testing).
	 */
	constructor(
		flushIntervalMs = 60_000,
		private counterFile: string = ''
	) {
		if (flushIntervalMs > 0) {
			// Periodically call flush.
			this._flushTimer = setInterval(this.flush.bind(this), flushIntervalMs);
		}
	}

	/**
	 * Initializes the tool.
	 * This method should be called once. Subsequent calls have no effect.
	 */
	public setTool(tool: string) {
		// Allow only once.
		if (tool === '' || this._state !== ReporterState.NOT_INITIALIZED) {
			return;
		}
		this._state = ReporterState.IDLE;
		this._tool = tool;
	}

	/**
	 * Adds a numeric value to a counter associated with the given key.
	 */
	public add(key: TelemetryKey, value: number) {
		if (value <= 0) {
			return;
		}
		const sanitized = key.replace(/[\s\n]/g, '_');
		this._counters[sanitized] = (this._counters[sanitized] || 0) + value;
	}

	/**
	 * Flushes Go telemetry data.
	 * * When `force` is true, telemetry is flushed immediately, bypassing the
	 * IDLE state check.
	 * * When `force` is false, telemetry is flushed only if the reporter is IDLE.
	 */
	public async flush(force = false) {
		// If flush runs with force=true, ignore the state and skip state update.
		if (!force && this._state !== ReporterState.IDLE) {
			// vscgo is not installed yet or is running. flush next time.
			return 0;
		}
		if (!force) {
			this._state = ReporterState.RUNNING;
		}
		try {
			await this.writeGoTelemetry();
		} catch (e) {
			console.log(`failed to flush telemetry data: ${e}`);
		} finally {
			if (!force) {
				this._state = ReporterState.IDLE;
			}
		}
	}

	private writeGoTelemetry() {
		const data = Object.entries(this._counters);
		if (data.length === 0) {
			return;
		}
		this._counters = {};

		let stderr = '';
		return new Promise<number | null>((resolve, reject) => {
			const env = toolExecutionEnvironment();
			if (this.counterFile !== '') {
				env['TELEMETRY_COUNTER_FILE'] = this.counterFile;
			}
			const p = cp.spawn(this._tool, ['inc_counters'], {
				cwd: getWorkspaceFolderPath(),
				env
			});

			p.stderr.on('data', (data) => {
				stderr += data;
			});

			// 'close' fires after exit or error when the subprocess closes all stdio.
			p.on('close', (exitCode, signal) => {
				if (exitCode !== 0) {
					reject(`exited with code=${exitCode} signal=${signal} stderr=${stderr}`);
				} else {
					resolve(exitCode);
				}
			});
			// Stream key/value to the vscgo process.
			data.forEach(([key, value]) => {
				p.stdin.write(`${key} ${value}\n`);
			});
			p.stdin.end();
		});
	}

	public async dispose() {
		if (this._flushTimer) {
			clearInterval(this._flushTimer);
		}
		this._flushTimer = undefined;
		await this.flush(true); // Flush any remaining data in buffer.
	}
}

/**
 * Global telemetryReporter instance.
 */
export const telemetryReporter = new TelemetryReporter();

// TODO(hyangah): consolidate the list of all the telemetries and bucketting functions.

export function addTelemetryEvent(name: TelemetryKey, count: number) {
	telemetryReporter.add(name, count);
}

/**
 * Go extension delegates most of the telemetry logic to gopls.
 * TelemetryService provides API to interact with gopls's telemetry.
 */
export class TelemetryService {
	private active = false;
	constructor(
		private languageClient: Pick<LanguageClient, 'sendRequest'> | undefined,
		private globalState: vscode.Memento,
		serverCommands: string[] = []
	) {
		if (!languageClient || !serverCommands.includes(GOPLS_MAYBE_PROMPT_FOR_TELEMETRY)) {
			// We are not backed by the gopls version that supports telemetry.
			return;
		}

		this.active = true;
		// Record the first time we see the gopls with telemetry support.
		// The timestamp will be used to avoid prompting too early.
		const telemetryStartTime = readTelemetryStartTime(globalState);
		if (!telemetryStartTime) {
			recordTelemetryStartTime(globalState, new Date());
		}
	}

	async promptForTelemetry(isVSCodeTelemetryEnabled: boolean = vscode.env.isTelemetryEnabled) {
		if (!this.active) return;

		// Do not prompt if the user disabled vscode's telemetry.
		// See https://code.visualstudio.com/api/extension-guides/telemetry#without-the-telemetry-module
		if (!isVSCodeTelemetryEnabled) return;

		// Allow at least 7days for gopls to collect some data.
		const telemetryStartTime = readTelemetryStartTime(this.globalState);
		if (!telemetryStartTime) {
			return;
		}
		if (daysBetween(telemetryStartTime, new Date()) < 7) {
			return;
		}

		try {
			await this.languageClient?.sendRequest(ExecuteCommandRequest.type, {
				command: GOPLS_MAYBE_PROMPT_FOR_TELEMETRY
			});
		} catch (e) {
			console.log(`failed to send telemetry request: ${e}`);
		}
	}
}

/**
 * Set telemetry env vars for gopls. See gopls/internal/server/prompt.go
 * TODO(hyangah): add an integration testing after gopls v0.17 becomes available.
 */
export function setTelemetryEnvVars(globalState: vscode.Memento, env: NodeJS.ProcessEnv) {
	if (!env['GOTELEMETRY_GOPLS_CLIENT_TOKEN']) {
		env['GOTELEMETRY_GOPLS_CLIENT_TOKEN'] = `${hashMachineID() + 1}`; // [1, 1000]
	}
	if (!env['GOTELEMETRY_GOPLS_CLIENT_START_TIME']) {
		const start = readTelemetryStartTime(globalState);
		if (start) {
			const unixSec = Math.floor(start.getTime() / 1000);
			env['GOTELEMETRY_GOPLS_CLIENT_START_TIME'] = `${unixSec}`;
		}
	}
}

/**
 * Map vscode.env.machineId to an integer in [0, 1000).
 */
function hashMachineID(salt?: string): number {
	const hash = createHash('md5').update(`${vscode.env.machineId}${salt}`).digest('hex');
	return parseInt(hash.substring(0, 8), 16) % 1000;
}
