//===-- NativeProcessTestUtils.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H
#define LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H

#include "lldb/Host/common/NativeProcessProtocol.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"

using namespace lldb_private;
using namespace lldb;
using namespace testing;

namespace lldb_private {

class MockDelegate : public NativeProcessProtocol::NativeDelegate {
public:
  MOCK_METHOD1(InitializeDelegate, void(NativeProcessProtocol *Process));
  MOCK_METHOD2(ProcessStateChanged,
               void(NativeProcessProtocol *Process, StateType State));
  MOCK_METHOD1(DidExec, void(NativeProcessProtocol *Process));
};

// NB: This class doesn't use the override keyword to avoid
// -Winconsistent-missing-override warnings from the compiler. The
// inconsistency comes from the overriding definitions in the MOCK_*** macros.
template <typename T> class MockProcess : public T {
public:
  MockProcess(NativeProcessProtocol::NativeDelegate &Delegate,
              const ArchSpec &Arch, lldb::pid_t Pid = 1)
      : T(Pid, -1, Delegate), Arch(Arch) {}

  MOCK_METHOD1(Resume, Status(const ResumeActionList &ResumeActions));
  MOCK_METHOD0(Halt, Status());
  MOCK_METHOD0(Detach, Status());
  MOCK_METHOD1(Signal, Status(int Signo));
  MOCK_METHOD0(Kill, Status());
  MOCK_METHOD0(GetSharedLibraryInfoAddress, addr_t());
  MOCK_METHOD0(UpdateThreads, size_t());
  MOCK_CONST_METHOD0(GetAuxvData,
                     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>());
  MOCK_METHOD2(GetLoadedModuleFileSpec,
               Status(const char *ModulePath, FileSpec &Spec));
  MOCK_METHOD2(GetFileLoadAddress,
               Status(const llvm::StringRef &FileName, addr_t &Addr));

  const ArchSpec &GetArchitecture() const /*override*/ { return Arch; }
  Status SetBreakpoint(lldb::addr_t Addr, uint32_t Size,
                       bool Hardware) /*override*/ {
    if (Hardware)
      return this->SetHardwareBreakpoint(Addr, Size);
    else
      return this->SetSoftwareBreakpoint(Addr, Size);
  }

  // Redirect base class Read/Write Memory methods to functions whose signatures
  // are more mock-friendly.
  Status ReadMemory(addr_t Addr, void *Buf, size_t Size,
                    size_t &BytesRead) /*override*/ {
    auto ExpectedMemory = this->ReadMemory(Addr, Size);
    if (!ExpectedMemory) {
      BytesRead = 0;
      return Status(ExpectedMemory.takeError());
    }
    BytesRead = ExpectedMemory->size();
    assert(BytesRead <= Size);
    std::memcpy(Buf, ExpectedMemory->data(), BytesRead);
    return Status();
  }

  Status WriteMemory(addr_t Addr, const void *Buf, size_t Size,
                     size_t &BytesWritten) /*override*/ {
    auto ExpectedBytes = this->WriteMemory(
        Addr, llvm::makeArrayRef(static_cast<const uint8_t *>(Buf), Size));
    if (!ExpectedBytes) {
      BytesWritten = 0;
      return Status(ExpectedBytes.takeError());
    }
    BytesWritten = *ExpectedBytes;
    return Status();
  }

  MOCK_METHOD2(ReadMemory,
               llvm::Expected<std::vector<uint8_t>>(addr_t Addr, size_t Size));
  MOCK_METHOD2(WriteMemory,
               llvm::Expected<size_t>(addr_t Addr,
                                      llvm::ArrayRef<uint8_t> Data));

  using T::GetSoftwareBreakpointTrapOpcode;
  llvm::Expected<std::vector<uint8_t>> ReadMemoryWithoutTrap(addr_t Addr,
                                                             size_t Size) {
    std::vector<uint8_t> Data(Size, 0);
    size_t BytesRead;
    Status ST =
        T::ReadMemoryWithoutTrap(Addr, Data.data(), Data.size(), BytesRead);
    if (ST.Fail())
      return ST.ToError();
    Data.resize(BytesRead);
    return std::move(Data);
  }

private:
  ArchSpec Arch;
};

class FakeMemory {
public:
  FakeMemory(llvm::ArrayRef<uint8_t> Data, addr_t start_addr = 0)
      : Data(Data), m_start_addr(start_addr) {}

  FakeMemory(const void *Data, size_t data_size, addr_t start_addr = 0)
      : Data((const uint8_t *)Data, ((const uint8_t *)Data) + data_size),
        m_start_addr(start_addr) {}

  llvm::Expected<std::vector<uint8_t>> Read(addr_t Addr, size_t Size) {
    Addr -= m_start_addr;
    if (Addr >= Data.size())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Address out of range.");
    Size = std::min(Size, Data.size() - (size_t)Addr);
    auto Begin = std::next(Data.begin(), Addr);
    return std::vector<uint8_t>(Begin, std::next(Begin, Size));
  }

  llvm::Expected<size_t> Write(addr_t Addr, llvm::ArrayRef<uint8_t> Chunk) {
    Addr -= m_start_addr;
    if (Addr >= Data.size())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Address out of range.");
    size_t Size = std::min(Chunk.size(), Data.size() - (size_t)Addr);
    std::copy_n(Chunk.begin(), Size, &Data[Addr]);
    return Size;
  }

private:
  std::vector<uint8_t> Data;
  addr_t m_start_addr;
};
} // namespace lldb_private

#endif
