//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===--------------------------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/OProfileWrapper.h"
#include "JITEventListenerTestCommon.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include <list>
#include <map>

using namespace llvm;

namespace {

struct OprofileNativeFunction {
  const char* Name;
  uint64_t Addr;
  const void* CodePtr;
  unsigned int CodeSize;

  OprofileNativeFunction(const char* name,
                         uint64_t addr,
                         const void* code,
                         unsigned int size)
  : Name(name)
  , Addr(addr)
  , CodePtr(code)
  , CodeSize(size) {
  }
};

typedef std::list<OprofileNativeFunction> NativeFunctionList;
typedef std::list<debug_line_info> NativeDebugList;
NativeFunctionList NativeFunctions;

NativeCodeMap ReportedDebugFuncs;

} // namespace

/// Mock implementaion of opagent library
namespace test_opagent {

op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);

op_agent_t open_agent()
{
  // return non-null op_agent_t
  return globalAgent;
}

int close_agent(op_agent_t agent)
{
  EXPECT_EQ(globalAgent, agent);
  return 0;
}

int write_native_code(op_agent_t agent,
                      const char* name,
                      uint64_t addr,
                      void const* code,
                      unsigned int size)
{
  EXPECT_EQ(globalAgent, agent);
  OprofileNativeFunction func(name, addr, code, size);
  NativeFunctions.push_back(func);

  // Verify no other registration has take place for the same address
  EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());

  ReportedDebugFuncs[addr];
  return 0;
}

int write_debug_line_info(op_agent_t agent,
                          void const* code,
                          size_t num_entries,
                          struct debug_line_info const* info)
{
  EXPECT_EQ(globalAgent, agent);

  //verify code has been loaded first
  uint64_t addr = reinterpret_cast<uint64_t>(code);
  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
  EXPECT_TRUE(i != ReportedDebugFuncs.end());

  NativeDebugList NativeInfo(info, info + num_entries);

  SourceLocations locs;
  for(NativeDebugList::iterator i = NativeInfo.begin();
      i != NativeInfo.end();
      ++i) {
    locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
  }
  ReportedDebugFuncs[addr] = locs;

  return 0;
}

int unload_native_code(op_agent_t agent, uint64_t addr) {
  EXPECT_EQ(globalAgent, agent);

  //verify that something for the given JIT addr has been loaded first
  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
  EXPECT_TRUE(i != ReportedDebugFuncs.end());
  ReportedDebugFuncs.erase(i);
  return 0;
}

int version() {
  return 1;
}

bool is_oprofile_running() {
  return true;
}

} //namespace test_opagent

class OProfileJITEventListenerTest
: public JITEventListenerTestBase<OProfileWrapper>
{
public:
  OProfileJITEventListenerTest()
  : JITEventListenerTestBase<OProfileWrapper>(
    new OProfileWrapper(test_opagent::open_agent,
      test_opagent::close_agent,
      test_opagent::write_native_code,
      test_opagent::write_debug_line_info,
      test_opagent::unload_native_code,
      test_opagent::version,
      test_opagent::version,
      test_opagent::is_oprofile_running))
  {
    EXPECT_TRUE(0 != MockWrapper);

    Listener.reset(JITEventListener::createOProfileJITEventListener(
      MockWrapper.get()));
    EXPECT_TRUE(0 != Listener);
    EE->RegisterJITEventListener(Listener.get());
  }
};

TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
  TestNoDebugInfo(ReportedDebugFuncs);
}

TEST_F(OProfileJITEventListenerTest, SingleLine) {
  TestSingleLine(ReportedDebugFuncs);
}

TEST_F(OProfileJITEventListenerTest, MultipleLines) {
  TestMultipleLines(ReportedDebugFuncs);
}

TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
  TestMultipleFiles(ReportedDebugFuncs);
}

testing::Environment* const jit_env =
  testing::AddGlobalTestEnvironment(new JITEnvironment);
