/*******************************************************************************
 * Copyright (c) 2009, 2011 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 "StdAfx.h"
#include "WinProcess.h"
#include "WinThread.h"
#include "EventClientNotifier.h"
#include "AgentUtils.h"
#include "Psapi.h"
#include "assert.h"
#include "WinDebugMonitor.h"
#include "TerminateProcessAction.h"
#include "ProtocolConstants.h"
#include "RunControlService.h"
#include "ContextManager.h"
#include "BreakpointsService.h"

std::map<int, WinProcess*> WinProcess::processIDMap;

WinProcess::WinProcess(WinDebugMonitor* monitor, DEBUG_EVENT& debugEvent)
  : ProcessContext(debugEvent.dwProcessId, ROOT_CONTEXT_ID, CreateInternalID(debugEvent.dwProcessId)),
	processHandle_(debugEvent.u.CreateProcessInfo.hProcess),
	monitor_(monitor)
{
	isRoot_ = true;
	processIDMap[debugEvent.dwProcessId] = this;

	// Get the name for the new process
	std::string moduleFileName = "unknown";
	int bufferSize = 32768;
	{
		LPTSTR processNameBuffer = new TCHAR[bufferSize];
		int nameLength = GetProcessImageFileName((HMODULE) processHandle_,
				processNameBuffer, bufferSize);
		if (nameLength > 0)
			moduleFileName = AgentUtils::makeString(processNameBuffer);

		delete[] processNameBuffer;
	}
	int lastSlash = moduleFileName.find_last_of("\\");
	if (lastSlash > 0)
		moduleFileName = moduleFileName.substr(lastSlash + 1);
	processName_ = moduleFileName;

	Initialize();
}

WinProcess::WinProcess(DWORD procID, std::string procName)
  : ProcessContext(procID, ROOT_CONTEXT_ID, CreateInternalID(procID)),
	processHandle_(NULL),
	monitor_(NULL)
{
	processName_ = procName;

	Initialize();
}

// Initialize process specific properties.
void WinProcess::Initialize() {
	SetProperty(PROP_NAME, PropertyValue(processName_));

	// do not support process stepping yet
	int supportedResumeModes = (1 << RM_RESUME);
	SetProperty(PROP_CAN_RESUME, PropertyValue(supportedResumeModes));

	SetProperty(PROP_CAN_TERMINATE, PropertyValue(true));
	SetProperty(PROP_CAN_SUSPEND, PropertyValue(true));
}

WinProcess::~WinProcess(void) {

	processIDMap.erase(GetOSID());

	GetMonitor()->ProcessDied(GetOSID());

	// Destructor of parent classes will be called which will
	// delete all children contexts (threads, registers, etc).
}

const HANDLE& WinProcess::GetProcessHandle() const {
	return processHandle_;
}

WinProcess* WinProcess::GetProcessByID(int processID) {
	std::map<int, WinProcess*>::iterator iter = processIDMap.find(processID);
	if (iter == processIDMap.end())
		return NULL;

	return iter->second;
}

int WinProcess::ReadMemory(const ReadWriteMemoryParams& params) throw (AgentException) {
	int result = 0;

	BOOL success
	  = ::ReadProcessMemory(processHandle_, (LPCVOID) params.address,
			  	  	  	    params.memBuffer, params.size, params.sizeTransferred);
	if (!success)
		result = ::GetLastError();
	else
		BreakpointsService::RemoveBreakpointsFromMemoryRead(processHandle_, params.address, params.memBuffer, params.size);

	return result;
}

int WinProcess::WriteMemory(const ReadWriteMemoryParams& params) throw (AgentException) {
	int result = 0;

	BOOL success
	  = ::WriteProcessMemory(processHandle_, (LPVOID) params.address,
			  	  	  	  	 params.memBuffer, params.size, params.sizeTransferred);
	if (!success)
		result = ::GetLastError();
	else {
		BreakpointsService::ReInsertBreakpointsAfterMemoryWrite(processHandle_, params.address, params.memBuffer, params.size);
	}
	return result;
}

void WinProcess::Terminate(const AgentActionParams& params) throw (AgentException) {
	if (monitor_)
		monitor_->PostAction(new TerminateProcessAction(params, GetOSID()));
}

// TODO: if we report an error, DSF gets confused...
// just report success even though it's not implemented
void WinProcess::SingleStep(const AgentActionParams& params) throw (AgentException) {
	AgentActionReply::postReply(params.channel, params.token, 0);
	//AgentActionReply::postReply(params.channel, params.token, ERR_UNSUPPORTED);
};


WinDebugMonitor* WinProcess::GetMonitor() const {
	return monitor_;
}

std::map<int, Properties>& WinProcess::GetExecutablesByAddress() {
	return executablesByAddress_;
}

void WinProcess::SetDebugRegister(WinHWBkptMgr::DRMask drMask, ContextAddress addr, WinHWBkptMgr::DRFlags flags) {
	const std::list<Context*>& children = GetChildren();
	std::list<Context*>::const_iterator c;
	for (c = children.begin(); c != children.end(); c++) {
		WinThread* winThread = dynamic_cast<WinThread*>(*c);
		if (winThread != NULL)
			winThread->SetDebugRegister(drMask, addr, flags);
	}
}

void WinProcess::ClearDebugRegister(WinHWBkptMgr::DRMask drMask) {
	const std::list<Context*>& children = GetChildren();
	std::list<Context*>::const_iterator c;
	for (c = children.begin(); c != children.end(); c++) {
		WinThread* winThread = dynamic_cast<WinThread*>(*c);
		if (winThread != NULL)
			winThread->ClearDebugRegister(drMask);
	}
}
