/*******************************************************************************
 * Copyright (c) 2010 Nokia and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Nokia - Initial API and implementation
 *******************************************************************************/
#include "ProcessService.h"

#include <algorithm>
#include <string>
#include <set>
#include <Tlhelp32.h>

#include "TCFHeaders.h"
#include "TCFChannel.h"
#include "WinDebugMonitor.h"
#include "WinProcess.h"
#include "AgentUtils.h"
#include "ContextManager.h"
#include "EventClientNotifier.h"
#include "Logger.h"
#include "DetachProcessAction.h"

static const char * sServiceName = "Processes";

static std::string quoteIfNeeded(const char* source);

ProcessService::ProcessService(Protocol * proto) :
	TCFService(proto) {
	AddCommand("getContext", command_get_context);
	AddCommand("getChildren", command_get_children);
	AddCommand("attach", command_attach);
	AddCommand("detach", command_detach);
	AddCommand("terminate", command_terminate);
	AddCommand("signal", command_signal);
	AddCommand("getEnvironment", command_get_environment);
	AddCommand("start", command_start);
}

ProcessService::~ProcessService(void) {
}

const char* ProcessService::GetName() {
	return sServiceName;
}

/*
 * This will return a context, running or debugged one.
 */
void ProcessService::command_get_context(const char * token, Channel * c) {
	LogTrace("ProcessService::command_get_context", "token: %s", token);
	TCFChannel channel(c);

	std::string id = channel.readString();
	channel.readZero();
	channel.readComplete();

	Context* context = ContextManager::findContext(id);
	if (context == NULL) {
		// Return an invalid context ID error.
		channel.writeCompleteReply(token, ERR_INV_CONTEXT, 1);
		return;
	}
	
	channel.writeReplyHeader(token);
	channel.writeError(0);
	EventClientNotifier::WriteContext(*context, channel);
	channel.writeZero();
	channel.writeComplete();
}

/** Filter to get choose Contexts which are the top-level RunControlContext that were from the
 * previous Processes::getChildren call.  Ignore those that are being debugged. */
static bool IsNotRunningProcessContext(const ContextID& contextID) {
	Context* context = ContextManager::findContext(contextID);
	ProcessContext* rcContext = dynamic_cast<ProcessContext*>(context);
	trace(LOG_ALWAYS, "Context %s: isRC=%d, isDebugging=%d", contextID.c_str(), rcContext!=0, rcContext && rcContext->IsDebugging());
	return !rcContext || rcContext->IsDebugging();
}
/** Remove and delete a context by value. */
static void RemoveAndDeleteContext(const ContextID& contextID) {
	trace(LOG_ALWAYS, "Removing context %s", contextID.c_str());
	delete ContextManager::removeContext(contextID);
}

void ProcessService::command_get_children(const char * token, Channel * c) {
    char id[256];
    int attached_only;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    attached_only = json_read_boolean(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);

    if (id[0] != 0) {
        write_errno(&c->out, 0);
        write_stringz(&c->out, "null");
    }
    else {
        DWORD err = 0;
        HANDLE snapshot;
        PROCESSENTRY32 pe32;

        snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (snapshot == INVALID_HANDLE_VALUE) err = set_win32_errno(GetLastError());
        memset(&pe32, 0, sizeof(pe32));
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if (!err && !Process32First(snapshot, &pe32)) {
            err = set_win32_errno(GetLastError());
            CloseHandle(snapshot);
        }
        write_errno(&c->out, err);
        if (err) {
            write_stringz(&c->out, "null");
        }
        else {
        	// Get all the known contexts
        	std::list<ContextID> runContexts = ContextManager::getContexts();

        	// Shuffle to the end the ones we want to remove
        	std::list<ContextID>::iterator removeEnd = std::remove_if(runContexts.begin(), runContexts.end(),
        			IsNotRunningProcessContext);

        	// Remove these entries from the manager
        	std::for_each(runContexts.begin(), removeEnd, RemoveAndDeleteContext);

            int cnt = 0;
            write_stream(&c->out, '[');

            do {
                if (!attached_only || WinProcess::GetProcessByID(pe32.th32ProcessID) != NULL) {
                    if (cnt > 0) write_stream(&c->out, ',');
                    // We just pass the OS process ID.

                    // If context still exists, it is being debugged, so leave it be.
					WinProcess* process = dynamic_cast<WinProcess*>(ContextManager::findContext(
							WinProcess::CreateInternalID(pe32.th32ProcessID)));

					if (!process) {
						process = new WinProcess(pe32.th32ProcessID, pe32.szExeFile);
						ContextManager::addContext(process);
					}

					// Tell host the unique internal ID.
					json_write_string(&c->out, process->GetID().c_str());

                    cnt++;
                }
            } while (Process32Next(snapshot, &pe32));

            write_stream(&c->out, ']');
            write_stream(&c->out, 0);
        }
        if (snapshot != INVALID_HANDLE_VALUE)
        	CloseHandle(snapshot);
    }

    write_stream(&c->out, MARKER_EOM);
}

void ProcessService::command_attach(const char * token, Channel * c) {
	LogTrace("ProcessService::command_attach", "token: %s", token);
	TCFChannel channel(c);
	std::string id = channel.readString();
	channel.readZero();
	channel.readComplete();

	RunControlContext* context = dynamic_cast<RunControlContext*>(ContextManager::findContext(id));

	// TODO: or not running
	if (context == NULL) {
		// Return an invalid context ID error.
		channel.writeCompleteReply(token, ERR_INV_CONTEXT);
		return;
	}
	
	// This function will report result to host debugger.

	AttachToProcessParams params(token, c, context->GetOSID(), true);
	WinDebugMonitor::AttachToProcess(params);

}

void ProcessService::command_detach(const char * token, Channel * c) {
	LogTrace("ProcessService::command_detach", "token: %s", token);
	TCFChannel channel(c);
	std::string id = channel.readString();
	channel.readZero();
	channel.readComplete();

	WinProcess* context = dynamic_cast<WinProcess*>(ContextManager::findContext(id));

	if (context == NULL || !context->IsDebugging()) {
		// Return an invalid context ID error.
		channel.writeCompleteReply(token, ERR_INV_CONTEXT);
		return;
	}

	context->GetMonitor()->PostAction(new DetachProcessAction(
			AgentActionParams(token, c), context->GetOSID()));
}

void ProcessService::command_terminate(const char * token, Channel * c) {
}

void ProcessService::command_signal(const char * token, Channel * c) {
}

void ProcessService::command_get_environment(const char * token, Channel * c) {
	char ** p = environ;

	TCFChannel channel(c);
	channel.readComplete();

	channel.writeReplyHeader(token);
	channel.writeError(0);

	channel.writeCharacter('[');
	if (p != NULL) {
		while (*p != NULL) {
			if (p != environ)
				channel.writeCharacter(',');
			json_write_string(&c->out, *p++);
		}
	}
	channel.writeCharacter(']');
	channel.writeZero();
	channel.writeComplete();
}

std::wstring json_read_string(Channel * c) {
	char stringbuffer[4096];
	json_read_string(&c->inp, stringbuffer, sizeof(stringbuffer));
	if (c->inp.read(&c->inp) != 0)
		exception(ERR_JSON_SYNTAX);

	int wideSize = MultiByteToWideChar(CP_UTF8, 0, stringbuffer, strlen(
			stringbuffer) + 1, NULL, 0);
	wchar_t* wideChars = new wchar_t[wideSize];
	MultiByteToWideChar(CP_UTF8, 0, stringbuffer, strlen(stringbuffer) + 1,
			wideChars, wideSize);
	std::wstring result = wideChars;
	delete[] wideChars;
	return result;
}

void ProcessService::command_start(const char * token, Channel * c) {
	TCFChannel channel(c);
	std::string directory = channel.readString();
	channel.readZero();
	std::string executable = channel.readString();
	channel.readZero();

	char ** args = NULL;
	char ** envp = NULL;
	int args_len = 0;
	int envp_len = 0;

	args = json_read_alloc_string_array(&c->inp, &args_len);
	if (c->inp.read(&c->inp) != 0)
		exception(ERR_JSON_SYNTAX);
	envp = json_read_alloc_string_array(&c->inp, &envp_len);
	if (c->inp.read(&c->inp) != 0)
		exception(ERR_JSON_SYNTAX);

	std::vector<std::string> environment;
	for (int i = 0; i < envp_len; i++)
	{
		environment.push_back(envp[i]);
	}

	// this is the "attach" parameter, but note that in this case
	// it's really if you want to stay attached to the process we're
	// launching in order to debug it, vs. just launching it in order
	// to run it (without debugging).  for attaching to an existing
	// process, command_attach will be called.
// TODO currently ignored, but we need to honor it if/when we add
// support for running vs. debugging.
/*	bool debug = */ json_read_boolean(&c->inp); // attach

	if (read_stream(&c->inp) != 0)
		exception(ERR_JSON_SYNTAX);
	channel.readComplete();

	std::string wargs;

	wargs += quoteIfNeeded(executable.c_str());
	for (int i = 0; i < args_len; i++) {
		wargs += ' ';
		wargs += quoteIfNeeded(args[i]);
	}

	loc_free(args);
	loc_free(envp);

	LaunchProcessParams params(token, c, executable, directory, wargs, environment, true);
	WinDebugMonitor::LaunchProcess(params);

}


/**
 * Escape a string for the Win32 command line.
 *
 * Adapted from Win32ProcessEx.c in spawner:
 *
 * Copyright (c) 2002, 2010 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     QNX Software Systems - initial API and implementation
 *     Wind River Systems, Inc.
 *******************************************************************************/

static std::string quoteIfNeeded(const char* source) {
	std::string target;
	int cpyLength = strlen(source);

	BOOL bSlash = FALSE;
	int i = 0;

#define QUOTATION_DO   0
#define QUOTATION_DONE 1
#define QUOTATION_NONE 2
#undef _T
#define _T(x) x

	int nQuotationMode = 0;

	if((_T('\"') == *source) && (_T('\"') == *(source + cpyLength - 1)))
		{
		nQuotationMode = QUOTATION_DONE;
		}
	else
	if(strchr(source, _T(' ')) == NULL)
		{
		// No reason to quotate term becase it doesn't have embedded spaces
		nQuotationMode = QUOTATION_NONE;
		}
	else
		{
		// Needs to be quotated
		nQuotationMode = QUOTATION_DO;
		target += _T('\"');
		}


	for(; i < cpyLength; ++i)
		{
		if(source[i] == _T('\\'))
			bSlash = TRUE;
		else
			{
			// Don't quote embracing quotation marks
			if((source[i] == _T('\"')) && !((nQuotationMode == QUOTATION_DONE) && ((i == 0) || (i == (cpyLength - 1))) ) )
				{
				if(!bSlash) // If still not escaped
					{
					target += _T('\\');
					}
				}
			bSlash = FALSE;
			}

		target += source[i];
		}

	if(nQuotationMode == QUOTATION_DO)
		{
		target += _T('\"');
		}

	return target;
}

