//===---------------------- RemoteObjectLayerTest.cpp ---------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
#include "llvm/ExecutionEngine/Orc/RemoteObjectLayer.h"
#include "OrcTestCommon.h"
#include "QueueChannel.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::orc;

namespace {

class MockObjectLayer {
public:

  using ObjHandleT = uint64_t;

  using ObjectPtr = std::unique_ptr<MemoryBuffer>;

  using LookupFn = std::function<JITSymbol(StringRef, bool)>;
  using SymbolLookupTable = std::map<ObjHandleT, LookupFn>;

  using AddObjectFtor =
    std::function<Expected<ObjHandleT>(ObjectPtr, SymbolLookupTable&)>;

  class ObjectNotFound : public remote::ResourceNotFound<ObjHandleT> {
  public:
    ObjectNotFound(ObjHandleT H) : ResourceNotFound(H, "Object handle") {}
  };

  MockObjectLayer(AddObjectFtor AddObject)
    : AddObject(std::move(AddObject)) {}

  Expected<ObjHandleT> addObject(ObjectPtr Obj,
            std::shared_ptr<JITSymbolResolver> Resolver) {
    return AddObject(std::move(Obj), SymTab);
  }

  Error removeObject(ObjHandleT H) {
    if (SymTab.count(H))
      return Error::success();
    else
      return make_error<ObjectNotFound>(H);
  }

  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
    for (auto KV : SymTab) {
      if (auto Sym = KV.second(Name, ExportedSymbolsOnly))
        return Sym;
      else if (auto Err = Sym.takeError())
        return std::move(Err);
    }
    return JITSymbol(nullptr);
  }

  JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
                         bool ExportedSymbolsOnly) {
    auto LI = SymTab.find(H);
    if (LI != SymTab.end())
      return LI->second(Name, ExportedSymbolsOnly);
    else
      return make_error<ObjectNotFound>(H);
  }

  Error emitAndFinalize(ObjHandleT H) {
    if (SymTab.count(H))
      return Error::success();
    else
      return make_error<ObjectNotFound>(H);
  }

private:
  AddObjectFtor AddObject;
  SymbolLookupTable SymTab;
};

using RPCEndpoint = rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>;

MockObjectLayer::ObjectPtr createTestObject() {
  OrcNativeTarget::initialize();
  auto TM = std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget());

  if (!TM)
    return nullptr;

  LLVMContext Ctx;
  ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule");
  MB.getModule()->setDataLayout(TM->createDataLayout());
  auto *Main = MB.createFunctionDecl(
      FunctionType::get(Type::getInt32Ty(Ctx),
                        {Type::getInt32Ty(Ctx),
                         Type::getInt8PtrTy(Ctx)->getPointerTo()},
                        false),
      "main");
  Main->getBasicBlockList().push_back(BasicBlock::Create(Ctx));
  IRBuilder<> B(&Main->back());
  B.CreateRet(ConstantInt::getSigned(Type::getInt32Ty(Ctx), 42));

  SimpleCompiler IRCompiler(*TM);
  return IRCompiler(*MB.getModule());
}

TEST(RemoteObjectLayer, AddObject) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError = [](Error Err) {
    logAllUnhandledErrors(std::move(Err), llvm::errs());
  };

  // Copy the bytes out of the test object: the copy will be used to verify
  // that the original is correctly transmitted over RPC to the mock layer.
  StringRef ObjBytes = TestObject->getBuffer();
  std::vector<char> ObjContents(ObjBytes.size());
  std::copy(ObjBytes.begin(), ObjBytes.end(), ObjContents.begin());

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);
  MockObjectLayer BaseLayer(
    [&ObjContents](MockObjectLayer::ObjectPtr Obj,
                   MockObjectLayer::SymbolLookupTable &SymTab) {

      // Check that the received object file content matches the original.
      StringRef RPCObjContents = Obj->getBuffer();
      EXPECT_EQ(RPCObjContents.size(), ObjContents.size())
        << "RPC'd object file has incorrect size";
      EXPECT_TRUE(std::equal(RPCObjContents.begin(), RPCObjContents.end(),
                             ObjContents.begin()))
        << "RPC'd object file content does not match original content";

      return 1;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  cantFail(Client.addObject(std::move(TestObject),
                            std::make_shared<NullLegacyResolver>()));
  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, AddObjectFailure) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError =
    [](Error Err) {
      auto ErrMsg = toString(std::move(Err));
      EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")
        << "Expected error string to be \"AddObjectFailure - Test Message\"";
    };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);
  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab)
        -> Expected<MockObjectLayer::ObjHandleT> {
      return make_error<StringError>("AddObjectFailure - Test Message",
                                     inconvertibleErrorCode());
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto HandleOrErr = Client.addObject(std::move(TestObject),
                                      std::make_shared<NullLegacyResolver>());

  EXPECT_FALSE(HandleOrErr) << "Expected error from addObject";

  auto ErrMsg = toString(HandleOrErr.takeError());
  EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")
    << "Expected error string to be \"AddObjectFailure - Test Message\"";

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}


TEST(RemoteObjectLayer, RemoveObject) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError = [](Error Err) {
    logAllUnhandledErrors(std::move(Err), llvm::errs());
  };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      SymTab[1] = MockObjectLayer::LookupFn();
      return 1;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto H = cantFail(Client.addObject(std::move(TestObject),
                                     std::make_shared<NullLegacyResolver>()));

  cantFail(Client.removeObject(H));

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, RemoveObjectFailure) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError =
    [](Error Err) {
      auto ErrMsg = toString(std::move(Err));
      EXPECT_EQ(ErrMsg, "Object handle 42 not found")
        << "Expected error string to be \"Object handle 42 not found\"";
    };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  // AddObject lambda does not update symbol table, so removeObject will treat
  // this as a bad object handle.
  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      return 42;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto H = cantFail(Client.addObject(std::move(TestObject),
                                     std::make_shared<NullLegacyResolver>()));

  auto Err = Client.removeObject(H);
  EXPECT_TRUE(!!Err) << "Expected error from removeObject";

  auto ErrMsg = toString(std::move(Err));
  EXPECT_EQ(ErrMsg, "Object handle 42 not found")
    << "Expected error string to be \"Object handle 42 not found\"";

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, FindSymbol) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError =
    [](Error Err) {
      auto ErrMsg = toString(std::move(Err));
      EXPECT_EQ(ErrMsg, "Could not find symbol 'badsymbol'")
        << "Expected error string to be \"Object handle 42 not found\"";
    };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  // AddObject lambda does not update symbol table, so removeObject will treat
  // this as a bad object handle.
  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      SymTab[42] =
        [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
          if (Name == "foobar")
            return JITSymbol(0x12348765, JITSymbolFlags::Exported);
          if (Name == "badsymbol")
            return make_error<JITSymbolNotFound>(Name);
          return nullptr;
        };
      return 42;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  cantFail(Client.addObject(std::move(TestObject),
                            std::make_shared<NullLegacyResolver>()));

  // Check that we can find and materialize a valid symbol.
  auto Sym1 = Client.findSymbol("foobar", true);
  EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";
  EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)
    << "Symbol 'foobar' does not return the correct address";

  {
    // Check that we can return a symbol containing an error.
    auto Sym2 = Client.findSymbol("badsymbol", true);
    EXPECT_FALSE(!!Sym2) << "Symbol 'badsymbol' should not be findable";
    auto Err = Sym2.takeError();
    EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";
    auto ErrMsg = toString(std::move(Err));
    EXPECT_EQ(ErrMsg, "Could not find symbol 'badsymbol'")
      << "Expected symbol-not-found error for Sym2";
  }

  {
    // Check that we can return a 'null' symbol.
    auto Sym3 = Client.findSymbol("baz", true);
    EXPECT_FALSE(!!Sym3) << "Symbol 'baz' should convert to false";
    auto Err = Sym3.takeError();
    EXPECT_FALSE(!!Err) << "Symbol 'baz' should not contain an error";
  }

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, FindSymbolIn) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError =
    [](Error Err) {
      auto ErrMsg = toString(std::move(Err));
      EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")
        << "Expected error string to be \"Object handle 42 not found\"";
    };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  // AddObject lambda does not update symbol table, so removeObject will treat
  // this as a bad object handle.
  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      SymTab[42] =
        [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
          if (Name == "foobar")
            return JITSymbol(0x12348765, JITSymbolFlags::Exported);
          return make_error<JITSymbolNotFound>(Name);
        };
      // Dummy symbol table entry - this should not be visible to
      // findSymbolIn.
      SymTab[43] =
        [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
          if (Name == "barbaz")
            return JITSymbol(0xdeadbeef, JITSymbolFlags::Exported);
          return make_error<JITSymbolNotFound>(Name);
        };

      return 42;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto H = cantFail(Client.addObject(std::move(TestObject),
                                     std::make_shared<NullLegacyResolver>()));

  auto Sym1 = Client.findSymbolIn(H, "foobar", true);

  EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";
  EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)
    << "Symbol 'foobar' does not return the correct address";

  auto Sym2 = Client.findSymbolIn(H, "barbaz", true);
  EXPECT_FALSE(!!Sym2) << "Symbol 'barbaz' should not be findable";
  auto Err = Sym2.takeError();
  EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";
  auto ErrMsg = toString(std::move(Err));
  EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")
    << "Expected symbol-not-found error for Sym2";

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, EmitAndFinalize) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError = [](Error Err) {
    logAllUnhandledErrors(std::move(Err), llvm::errs());
  };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      SymTab[1] = MockObjectLayer::LookupFn();
      return 1;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto H = cantFail(Client.addObject(std::move(TestObject),
                                     std::make_shared<NullLegacyResolver>()));

  auto Err = Client.emitAndFinalize(H);
  EXPECT_FALSE(!!Err) << "emitAndFinalize should work";

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

TEST(RemoteObjectLayer, EmitAndFinalizeFailure) {
  llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
  auto TestObject = createTestObject();
  if (!TestObject)
    return;

  auto Channels = createPairedQueueChannels();

  auto ReportError =
    [](Error Err) {
      auto ErrMsg = toString(std::move(Err));
      EXPECT_EQ(ErrMsg, "Object handle 1 not found")
        << "Expected bad handle error";
    };

  RPCEndpoint ClientEP(*Channels.first, true);
  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);

  RPCEndpoint ServerEP(*Channels.second, true);

  MockObjectLayer BaseLayer(
    [](MockObjectLayer::ObjectPtr Obj,
       MockObjectLayer::SymbolLookupTable &SymTab) {
      return 1;
    });
  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
                                                               ServerEP,
                                                               ReportError);

  bool Finished = false;
  ServerEP.addHandler<remote::utils::TerminateSession>(
    [&]() { Finished = true; }
  );

  auto ServerThread =
    std::thread([&]() {
      while (!Finished)
        cantFail(ServerEP.handleOne());
    });

  auto H = cantFail(Client.addObject(std::move(TestObject),
                                     std::make_shared<NullLegacyResolver>()));

  auto Err = Client.emitAndFinalize(H);
  EXPECT_TRUE(!!Err) << "emitAndFinalize should work";

  auto ErrMsg = toString(std::move(Err));
  EXPECT_EQ(ErrMsg, "Object handle 1 not found")
    << "emitAndFinalize returned incorrect error";

  cantFail(ClientEP.callB<remote::utils::TerminateSession>());
  ServerThread.join();
}

}
