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

// NOTE: This debug adapter is experimental, in-development code. If you
// actually need to debug Go code, please use the default adapter.

import { ChildProcess, spawn } from 'child_process';
import * as fs from 'fs';
import net = require('net');
import * as os from 'os';
import * as path from 'path';

import {
	logger,
	Logger,
	LoggingDebugSession,
	OutputEvent,
	TerminatedEvent
} from 'vscode-debugadapter';
import { DebugProtocol } from 'vscode-debugprotocol';

import {
	envPath,
	getBinPathWithPreferredGopathGoroot,
	parseEnvFile
} from '../goPath';

import {killProcessTree} from '../processUtils';

import { DAPClient } from './dapClient';

interface LoadConfig {
	// FollowPointers requests pointers to be automatically dereferenced.
	followPointers: boolean;
	// MaxVariableRecurse is how far to recurse when evaluating nested types.
	maxVariableRecurse: number;
	// MaxStringLen is the maximum number of bytes read from a string
	maxStringLen: number;
	// MaxArrayValues is the maximum number of elements read from an array, a slice or a map.
	maxArrayValues: number;
	// MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields.
	maxStructFields: number;
}

// This interface should always match the schema found in `package.json`.
interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
	request: 'launch';
	[key: string]: any;
	program: string;
	stopOnEntry?: boolean;
	args?: string[];
	showLog?: boolean;
	logOutput?: string;
	cwd?: string;
	env?: { [key: string]: string };
	mode?: 'auto' | 'debug' | 'remote' | 'test' | 'exec';
	remotePath?: string;
	port?: number;
	host?: string;
	buildFlags?: string;
	init?: string;
	trace?: 'verbose' | 'log' | 'error';
	/** Optional path to .env file. */
	envFile?: string | string[];
	backend?: string;
	output?: string;
	/** Delve LoadConfig parameters */
	dlvLoadConfig?: LoadConfig;
	dlvToolPath: string;
	/** Delve Version */
	apiVersion: number;
	/** Delve maximum stack trace depth */
	stackTraceDepth: number;

	showGlobalVariables?: boolean;
	packagePathToGoModPathMap: { [key: string]: string };
}

interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
	request: 'attach';
	processId?: number;
	stopOnEntry?: boolean;
	showLog?: boolean;
	logOutput?: string;
	cwd?: string;
	mode?: 'local' | 'remote';
	remotePath?: string;
	port?: number;
	host?: string;
	trace?: 'verbose' | 'log' | 'error';
	backend?: string;
	/** Delve LoadConfig parameters */
	dlvLoadConfig?: LoadConfig;
	dlvToolPath: string;
	/** Delve Version */
	apiVersion: number;
	/** Delve maximum stack trace depth */
	stackTraceDepth: number;

	showGlobalVariables?: boolean;
}

process.on('uncaughtException', (err: any) => {
	const errMessage = err && (err.stack || err.message);
	logger.error(`Unhandled error in debug adapter: ${errMessage}`);
	throw err;
});

function logArgsToString(args: any[]): string {
	return args
		.map((arg) => {
			return typeof arg === 'string' ? arg : JSON.stringify(arg);
		})
		.join(' ');
}

function log(...args: any[]) {
	logger.warn(logArgsToString(args));
}

function logError(...args: any[]) {
	logger.error(logArgsToString(args));
}

// GoDlvDapDebugSession implements a DAP debug adapter to talk to the editor.
//
// This adapter serves as a DAP proxy between the editor and the DAP server
// inside Delve. It relies on functionality inherited from DebugSession to
// implement the server side interfacing the editor, and on DapClient to
// implement the client side interfacing Delve:
//
//      Editor                GoDlvDapDebugSession                 Delve
//  +------------+        +--------------+-----------+         +------------+
//  | DAP Client | <====> | DebugSession | DAPClient |  <====> | DAP Server |
//  +------------+        +--------------+-----------+         +------------+
export class GoDlvDapDebugSession extends LoggingDebugSession {
	private readonly DEFAULT_DELVE_HOST = '127.0.0.1';
	private readonly DEFAULT_DELVE_PORT = 42042;

	private logLevel: Logger.LogLevel = Logger.LogLevel.Error;

	private dlvClient: DelveClient = null;

	// Child process used to track debugee launched without debugging (noDebug
	// mode). Either debugProcess or dlvClient are null.
	private debugProcess: ChildProcess = null;

	public constructor() {
		super();

		// Invoke logger.init here because we want logging to work in 'inline'
		// DA mode. It's typically called in the start() method of our parent
		// class, but this method isn't called in 'inline' mode.
		logger.init((e) => this.sendEvent(e));

		// this debugger uses zero-based lines and columns
		this.setDebuggerLinesStartAt1(false);
		this.setDebuggerColumnsStartAt1(false);
	}

	protected initializeRequest(
		response: DebugProtocol.InitializeResponse,
		args: DebugProtocol.InitializeRequestArguments,
		request?: DebugProtocol.Request
	): void {
		log('InitializeRequest');
		response.body.supportsConfigurationDoneRequest = true;

		// We respond to InitializeRequest here, because Delve hasn't been
		// launched yet. Delve will start responding to DAP requests after
		// LaunchRequest is received, which tell us how to start it.

		// TODO: we could send an InitializeRequest to Delve when
		// it launches, wait for its response and sanity check the capabilities
		// it reports. Once DAP support in Delve is complete, this can be part
		// of making sure that the "dlv" binary we find is sufficiently
		// up-to-date to talk DAP with us.
		this.sendResponse(response);
		log('InitializeResponse');
	}

	protected launchRequest(
		response: DebugProtocol.LaunchResponse,
		args: LaunchRequestArguments,
		request: DebugProtocol.Request
	): void {
		// Setup logger now that we have the 'trace' level passed in from
		// LaunchRequestArguments.
		this.logLevel =
			args.trace === 'verbose'
				? Logger.LogLevel.Verbose
				: args.trace === 'log'
					? Logger.LogLevel.Log
					: Logger.LogLevel.Error;
		const logPath =
			this.logLevel !== Logger.LogLevel.Error ? path.join(os.tmpdir(), 'vscode-godlvdapdebug.txt') : undefined;
		logger.setup(this.logLevel, logPath);
		log('launchRequest');

		// In noDebug mode, we don't launch Delve.
		// TODO: this logic is currently organized for compatibility with the
		// existing DA. It's not clear what we should do in case noDebug is
		// set and mode isn't 'debug'. Sending an error response could be
		// a safe option.
		if (args.noDebug && args.mode === 'debug') {
			try {
				this.launchNoDebug(args);
			} catch (e) {
				logError(`launchNoDebug failed: "${e}"`);
				// TODO: define error constants
				// https://github.com/golang/vscode-go/issues/305
				this.sendErrorResponse(
					response,
					3000,
					`Failed to launch "${e}"`);
			}
			return;
		}

		if (!args.port) {
			args.port = this.DEFAULT_DELVE_PORT;
		}
		if (!args.host) {
			args.host = this.DEFAULT_DELVE_HOST;
		}

		this.dlvClient = new DelveClient(args);

		this.dlvClient.on('stdout', (str) => {
			log('dlv stdout:', str);
		});

		this.dlvClient.on('stderr', (str) => {
			log('dlv stderr:', str);
		});

		this.dlvClient.on('connected', () => {
			this.dlvClient.send(request);
		});

		this.dlvClient.on('close', (rc) => {
			if (rc !== 0) {
				// TODO: define error constants
				// https://github.com/golang/vscode-go/issues/305
				this.sendErrorResponse(
					response,
					3000,
					'Failed to continue: Check the debug console for details.');
			}
			log('Sending TerminatedEvent as delve is closed');
			this.sendEvent(new TerminatedEvent());
		});

		// Relay events and responses back to vscode. In the future we will
		// add middleware here to intercept specific kinds of responses/events
		// for special handling.
		this.dlvClient.on('event', (event) => {
			this.sendEvent(event);
		});

		this.dlvClient.on('response', (resp) => {
			this.sendResponse(resp);
		});
	}

	protected attachRequest(
		response: DebugProtocol.AttachResponse,
		args: AttachRequestArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected disconnectRequest(
		response: DebugProtocol.DisconnectResponse,
		args: DebugProtocol.DisconnectArguments,
		request?: DebugProtocol.Request
	): void {
		log('DisconnectRequest');
		// How we handle DisconnectRequest depends on whether Delve was launched
		// at all.
		// * In noDebug node, the Go program was spawned directly without
		//   debugging: this.debugProcess will be non-null, and this.dlvClient
		//   will be null.
		// * Otherwise, Delve was spawned: this.debugProcess will be null, and
		//   this.dlvClient will be non-null.
		if (this.debugProcess !== null) {
			log(`killing debugee (pid: ${this.debugProcess.pid})...`);

			// Kill the debugee and notify the client when the killing is
			// completed, to ensure a clean shutdown sequence.
			killProcessTree(this.debugProcess, log).then(() => {
				super.disconnectRequest(response, args);
				log('DisconnectResponse');
			});
		} else if (this.dlvClient !== null) {
			// Forward this DisconnectRequest to Delve.
			this.dlvClient.send(request);
		} else {
			logError(`both debug process and dlv client are null`);
			// TODO: define all error codes as constants
			// https://github.com/golang/vscode-go/issues/305
			this.sendErrorResponse(
				response,
				3000,
				'Failed to disconnect: Check the debug console for details.');
		}
	}

	protected terminateRequest(
		response: DebugProtocol.TerminateResponse,
		args: DebugProtocol.TerminateArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected restartRequest(
		response: DebugProtocol.RestartResponse,
		args: DebugProtocol.RestartArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setBreakPointsRequest(
		response: DebugProtocol.SetBreakpointsResponse,
		args: DebugProtocol.SetBreakpointsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setFunctionBreakPointsRequest(
		response: DebugProtocol.SetFunctionBreakpointsResponse,
		args: DebugProtocol.SetFunctionBreakpointsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setExceptionBreakPointsRequest(
		response: DebugProtocol.SetExceptionBreakpointsResponse,
		args: DebugProtocol.SetExceptionBreakpointsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected configurationDoneRequest(
		response: DebugProtocol.ConfigurationDoneResponse,
		args: DebugProtocol.ConfigurationDoneArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected continueRequest(
		response: DebugProtocol.ContinueResponse,
		args: DebugProtocol.ContinueArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected nextRequest(
		response: DebugProtocol.NextResponse,
		args: DebugProtocol.NextArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected stepInRequest(
		response: DebugProtocol.StepInResponse,
		args: DebugProtocol.StepInArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected stepOutRequest(
		response: DebugProtocol.StepOutResponse,
		args: DebugProtocol.StepOutArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected stepBackRequest(
		response: DebugProtocol.StepBackResponse,
		args: DebugProtocol.StepBackArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected reverseContinueRequest(
		response: DebugProtocol.ReverseContinueResponse,
		args: DebugProtocol.ReverseContinueArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected restartFrameRequest(
		response: DebugProtocol.RestartFrameResponse,
		args: DebugProtocol.RestartFrameArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected gotoRequest(
		response: DebugProtocol.GotoResponse,
		args: DebugProtocol.GotoArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected pauseRequest(
		response: DebugProtocol.PauseResponse,
		args: DebugProtocol.PauseArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected sourceRequest(
		response: DebugProtocol.SourceResponse,
		args: DebugProtocol.SourceArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected threadsRequest(
		response: DebugProtocol.ThreadsResponse,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected terminateThreadsRequest(
		response: DebugProtocol.TerminateThreadsResponse,
		args: DebugProtocol.TerminateThreadsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected stackTraceRequest(
		response: DebugProtocol.StackTraceResponse,
		args: DebugProtocol.StackTraceArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected scopesRequest(
		response: DebugProtocol.ScopesResponse,
		args: DebugProtocol.ScopesArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected variablesRequest(
		response: DebugProtocol.VariablesResponse,
		args: DebugProtocol.VariablesArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setVariableRequest(
		response: DebugProtocol.SetVariableResponse,
		args: DebugProtocol.SetVariableArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setExpressionRequest(
		response: DebugProtocol.SetExpressionResponse,
		args: DebugProtocol.SetExpressionArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected evaluateRequest(
		response: DebugProtocol.EvaluateResponse,
		args: DebugProtocol.EvaluateArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected stepInTargetsRequest(
		response: DebugProtocol.StepInTargetsResponse,
		args: DebugProtocol.StepInTargetsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected gotoTargetsRequest(
		response: DebugProtocol.GotoTargetsResponse,
		args: DebugProtocol.GotoTargetsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected completionsRequest(
		response: DebugProtocol.CompletionsResponse,
		args: DebugProtocol.CompletionsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected exceptionInfoRequest(
		response: DebugProtocol.ExceptionInfoResponse,
		args: DebugProtocol.ExceptionInfoArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected loadedSourcesRequest(
		response: DebugProtocol.LoadedSourcesResponse,
		args: DebugProtocol.LoadedSourcesArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected dataBreakpointInfoRequest(
		response: DebugProtocol.DataBreakpointInfoResponse,
		args: DebugProtocol.DataBreakpointInfoArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setDataBreakpointsRequest(
		response: DebugProtocol.SetDataBreakpointsResponse,
		args: DebugProtocol.SetDataBreakpointsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected readMemoryRequest(
		response: DebugProtocol.ReadMemoryResponse,
		args: DebugProtocol.ReadMemoryArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected disassembleRequest(
		response: DebugProtocol.DisassembleResponse,
		args: DebugProtocol.DisassembleArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected cancelRequest(
		response: DebugProtocol.CancelResponse,
		args: DebugProtocol.CancelArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected breakpointLocationsRequest(
		response: DebugProtocol.BreakpointLocationsResponse,
		args: DebugProtocol.BreakpointLocationsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	protected setInstructionBreakpointsRequest(
		response: DebugProtocol.SetInstructionBreakpointsResponse,
		args: DebugProtocol.SetInstructionBreakpointsArguments,
		request?: DebugProtocol.Request
	): void {
		this.dlvClient.send(request);
	}

	// Launch the debugee process without starting a debugger.
	// This implements the `Run > Run Without Debugger` functionality in vscode.
	// Note: this method currently assumes launchArgs.mode === 'debug'.
	private launchNoDebug(launchArgs: LaunchRequestArguments): void {
		const program = launchArgs.program;
		if (!program) {
			throw new Error('The program attribute is missing in the debug configuration in launch.json');
		}
		let programIsDirectory = false;
		try {
			programIsDirectory = fs.lstatSync(program).isDirectory();
		} catch (e) {
			throw new Error('The program attribute must point to valid directory, .go file or executable.');
		}
		if (!programIsDirectory && path.extname(program) !== '.go') {
			throw new Error('The program attribute must be a directory or .go file in debug mode');
		}

		const goRunArgs = ['run'];
		if (launchArgs.buildFlags) {
			goRunArgs.push(launchArgs.buildFlags);
		}

		if (programIsDirectory) {
			goRunArgs.push('.');
		} else {
			goRunArgs.push(program);
		}

		if (launchArgs.args) {
			goRunArgs.push(...launchArgs.args);
		}

		// Read env from disk and merge into env variables.
		const fileEnvs = [];
		if (typeof launchArgs.envFile === 'string') {
			fileEnvs.push(parseEnvFile(launchArgs.envFile));
		}
		if (Array.isArray(launchArgs.envFile)) {
			launchArgs.envFile.forEach((envFile) => {
				fileEnvs.push(parseEnvFile(envFile));
			});
		}

		const launchArgsEnv = launchArgs.env || {};
		const programEnv = Object.assign({}, process.env, ...fileEnvs, launchArgsEnv);

		const dirname = programIsDirectory ? program : path.dirname(program);
		const goExe = getBinPathWithPreferredGopathGoroot('go', []);
		log(`Current working directory: ${dirname}`);
		log(`Running: ${goExe} ${goRunArgs.join(' ')}`);

		this.debugProcess = spawn(goExe, goRunArgs, {
			cwd: dirname,
			env: programEnv
		});
		this.debugProcess.stderr.on('data', (str) => {
			this.sendEvent(new OutputEvent(str.toString(), 'stderr'));
		});
		this.debugProcess.stdout.on('data', (str) => {
			this.sendEvent(new OutputEvent(str.toString(), 'stdout'));
		});
		this.debugProcess.on('close', (rc) => {
			this.sendEvent(new TerminatedEvent());
		});
	}
}

// DelveClient provides a DAP client to talk to a DAP server in Delve.
//
// After creation, it emits the following events:
//
//    'connected':            delve is connected to delve
//    'request (request)':    delve sent request
//    'response (response)':  delve sent response
//    'event (event)':        delve sent event
//    'stdout' (str):         delve emitted str to stdout
//    'stderr' (str):         delve emitted str to stderr
//    'close' (rc):           delve exited with return code rc
class DelveClient extends DAPClient {
	private debugProcess: ChildProcess;
	private serverStarted: boolean = false;

	constructor(launchArgs: LaunchRequestArguments) {
		super();

		const launchArgsEnv = launchArgs.env || {};
		const env = Object.assign({}, process.env, launchArgsEnv);

		// Let users override direct path to delve by setting it in the env
		// map in launch.json; if unspecified, fall back to dlvToolPath.
		let dlvPath = launchArgsEnv['dlvPath'];
		if (!dlvPath) {
			dlvPath = launchArgs.dlvToolPath;
		}

		if (!fs.existsSync(dlvPath)) {
			log(
				`Couldn't find dlv at the Go tools path, ${process.env['GOPATH']}${
				env['GOPATH'] ? ', ' + env['GOPATH'] : ''
				} or ${envPath}`
			);
			throw new Error(
				`Cannot find Delve debugger. Install from https://github.com/go-delve/delve/ & ensure it is in your Go tools path, "GOPATH/bin" or "PATH".`
			);
		}

		const dlvArgs = new Array<string>();
		dlvArgs.push('dap');
		dlvArgs.push(`--listen=${launchArgs.host}:${launchArgs.port}`);
		if (launchArgs.showLog) {
			dlvArgs.push('--log=' + launchArgs.showLog.toString());
		}
		if (launchArgs.logOutput) {
			dlvArgs.push('--log-output=' + launchArgs.logOutput);
		}

		log(`Running: ${dlvPath} ${dlvArgs.join(' ')}`);

		this.debugProcess = spawn(dlvPath, dlvArgs, {
			cwd: path.dirname(launchArgs.program),
			env
		});

		this.debugProcess.stderr.on('data', (chunk) => {
			const str = chunk.toString();
			this.emit('stderr', str);
		});

		this.debugProcess.stdout.on('data', (chunk) => {
			const str = chunk.toString();
			this.emit('stdout', str);

			if (!this.serverStarted) {
				this.serverStarted = true;
				this.connectSocketToServer(launchArgs.port, launchArgs.host);
			}
		});

		this.debugProcess.on('close', (rc) => {
			if (rc) {
				logError(`Process exiting with code: ${rc} signal: ${this.debugProcess.killed}`);
			} else {
				log(`Process exiting normally ${this.debugProcess.killed}`);
			}
			this.emit('close', rc);
		});

		this.debugProcess.on('error', (err) => {
			throw err;
		});
	}

	// Connect this client to the server. The server is expected to be listening
	// on host:port.
	private connectSocketToServer(port: number, host: string) {
		// Add a slight delay to ensure that Delve started up the server.
		setTimeout(() => {
			const socket = net.createConnection(
				port,
				host,
				() => {
					this.connect(socket, socket);
					this.emit('connected');
				});

			socket.on('error', (err) => {
				throw err;
			});
		}, 200);
	}
}
