#include "llvm/Config/config.h"
#include "../RPCChannel.h"
#include "../RemoteTarget.h"
#include "../RemoteTargetMessage.h"
#include "llvm/Support/Memory.h"
#include <assert.h>
#include <map>
#include <stdint.h>
#include <string>
#include <vector>

using namespace llvm;

class LLIChildTarget {
public:
  void initialize();
  LLIMessageType waitForIncomingMessage();
  void handleMessage(LLIMessageType messageType);
  RemoteTarget *RT;
  RPCChannel RPC;

private:
  // Incoming message handlers
  void handleAllocateSpace();
  void handleLoadSection(bool IsCode);
  void handleExecute();

  // Outgoing message handlers
  void sendChildActive();
  void sendAllocationResult(uint64_t Addr);
  void sendLoadStatus(uint32_t Status);
  void sendExecutionComplete(int Result);

  // OS-specific functions
  void initializeConnection();
  int WriteBytes(const void *Data, size_t Size) {
    return RPC.WriteBytes(Data, Size) ? Size : -1;
  }
  int ReadBytes(void *Data, size_t Size) {
    return RPC.ReadBytes(Data, Size) ? Size : -1;
  }

  // Communication handles (OS-specific)
  void *ConnectionData;
};

int main() {
  LLIChildTarget  ThisChild;
  ThisChild.RT = new RemoteTarget();
  ThisChild.initialize();
  LLIMessageType MsgType;
  do {
    MsgType = ThisChild.waitForIncomingMessage();
    ThisChild.handleMessage(MsgType);
  } while (MsgType != LLI_Terminate &&
           MsgType != LLI_Error);
  delete ThisChild.RT;
  return 0;
}

// Public methods
void LLIChildTarget::initialize() {
  RPC.createClient();
  sendChildActive();
}

LLIMessageType LLIChildTarget::waitForIncomingMessage() {
  int32_t MsgType = -1;
  if (ReadBytes(&MsgType, 4) > 0)
    return (LLIMessageType)MsgType;
  return LLI_Error;
}

void LLIChildTarget::handleMessage(LLIMessageType messageType) {
  switch (messageType) {
    case LLI_AllocateSpace:
      handleAllocateSpace();
      break;
    case LLI_LoadCodeSection:
      handleLoadSection(true);
      break;
    case LLI_LoadDataSection:
      handleLoadSection(false);
      break;
    case LLI_Execute:
      handleExecute();
      break;
    case LLI_Terminate:
      RT->stop();
      break;
    default:
      // FIXME: Handle error!
      break;
  }
}

// Incoming message handlers
void LLIChildTarget::handleAllocateSpace() {
  // Read and verify the message data size.
  uint32_t DataSize;
  int rc = ReadBytes(&DataSize, 4);
  (void)rc;
  assert(rc == 4);
  assert(DataSize == 8);

  // Read the message arguments.
  uint32_t Alignment;
  uint32_t AllocSize;
  rc = ReadBytes(&Alignment, 4);
  assert(rc == 4);
  rc = ReadBytes(&AllocSize, 4);
  assert(rc == 4);

  // Allocate the memory.
  uint64_t Addr;
  RT->allocateSpace(AllocSize, Alignment, Addr);

  // Send AllocationResult message.
  sendAllocationResult(Addr);
}

void LLIChildTarget::handleLoadSection(bool IsCode) {
  // Read the message data size.
  uint32_t DataSize;
  int rc = ReadBytes(&DataSize, 4);
  (void)rc;
  assert(rc == 4);

  // Read the target load address.
  uint64_t Addr;
  rc = ReadBytes(&Addr, 8);
  assert(rc == 8);
  size_t BufferSize = DataSize - 8;

  if (!RT->isAllocatedMemory(Addr, BufferSize))
    return sendLoadStatus(LLI_Status_NotAllocated);

  // Read section data into previously allocated buffer
  rc = ReadBytes((void*)Addr, BufferSize);
  if (rc != (int)(BufferSize))
    return sendLoadStatus(LLI_Status_IncompleteMsg);

  // If IsCode, mark memory executable
  if (IsCode)
    sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);

  // Send MarkLoadComplete message.
  sendLoadStatus(LLI_Status_Success);
}

void LLIChildTarget::handleExecute() {
  // Read the message data size.
  uint32_t DataSize;
  int rc = ReadBytes(&DataSize, 4);
  (void)rc;
  assert(rc == 4);
  assert(DataSize == 8);

  // Read the target address.
  uint64_t Addr;
  rc = ReadBytes(&Addr, 8);
  assert(rc == 8);

  // Call function
  int32_t Result = -1;
  RT->executeCode(Addr, Result);

  // Send ExecutionResult message.
  sendExecutionComplete(Result);
}

// Outgoing message handlers
void LLIChildTarget::sendChildActive() {
  // Write the message type.
  uint32_t MsgType = (uint32_t)LLI_ChildActive;
  int rc = WriteBytes(&MsgType, 4);
  (void)rc;
  assert(rc == 4);

  // Write the data size.
  uint32_t DataSize = 0;
  rc = WriteBytes(&DataSize, 4);
  assert(rc == 4);
}

void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
  // Write the message type.
  uint32_t MsgType = (uint32_t)LLI_AllocationResult;
  int rc = WriteBytes(&MsgType, 4);
  (void)rc;
  assert(rc == 4);

  // Write the data size.
  uint32_t DataSize = 8;
  rc = WriteBytes(&DataSize, 4);
  assert(rc == 4);

  // Write the allocated address.
  rc = WriteBytes(&Addr, 8);
  assert(rc == 8);
}

void LLIChildTarget::sendLoadStatus(uint32_t Status) {
  // Write the message type.
  uint32_t MsgType = (uint32_t)LLI_LoadResult;
  int rc = WriteBytes(&MsgType, 4);
  (void)rc;
  assert(rc == 4);

  // Write the data size.
  uint32_t DataSize = 4;
  rc = WriteBytes(&DataSize, 4);
  assert(rc == 4);

  // Write the result.
  rc = WriteBytes(&Status, 4);
  assert(rc == 4);
}

void LLIChildTarget::sendExecutionComplete(int Result) {
  // Write the message type.
  uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
  int rc = WriteBytes(&MsgType, 4);
  (void)rc;
  assert(rc == 4);


  // Write the data size.
  uint32_t DataSize = 4;
  rc = WriteBytes(&DataSize, 4);
  assert(rc == 4);

  // Write the result.
  rc = WriteBytes(&Result, 4);
  assert(rc == 4);
}

#ifdef LLVM_ON_UNIX
#include "../Unix/RPCChannel.inc"
#endif

#ifdef LLVM_ON_WIN32
#include "../Windows/RPCChannel.inc"
#endif
