#include <pdx/service.h>

#include <memory>
#include <string>

#include <gmock/gmock.h>
#include <pdx/mock_service_endpoint.h>

using android::pdx::BorrowedChannelHandle;
using android::pdx::BorrowedHandle;
using android::pdx::Channel;
using android::pdx::ChannelReference;
using android::pdx::ErrorStatus;
using android::pdx::FileReference;
using android::pdx::LocalChannelHandle;
using android::pdx::LocalHandle;
using android::pdx::Message;
using android::pdx::MessageInfo;
using android::pdx::MockEndpoint;
using android::pdx::RemoteChannelHandle;
using android::pdx::RemoteHandle;
using android::pdx::Service;
using android::pdx::Status;

using testing::A;
using testing::ByMove;
using testing::DoAll;
using testing::Invoke;
using testing::Matcher;
using testing::Ref;
using testing::Return;
using testing::SetArgPointee;
using testing::WithArg;
using testing::WithoutArgs;
using testing::_;

namespace {

// Helper functions to construct fake void pointers for tests.
inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }

// Helper matchers for working with iovec structures in tests.
// Simple matcher for one element iovec array:
// EXPECT_CALL(mock, method(IoVecMatcher(ptr, size)));
MATCHER_P2(IoVecMatcher, ptr, size, "") {
  return arg->iov_base == ptr && arg->iov_len == size;
}

// Matcher for an array of iovecs:
// EXPECT_CALL(mock,
//             method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}})));
using IoVecArray = std::vector<iovec>;
MATCHER_P(IoVecMatcher, iovec_array, "") {
  for (const iovec& item : iovec_array) {
    if (arg->iov_base != item.iov_base || arg->iov_len != item.iov_len)
      return false;
    arg++;
  }
  return true;
}

using IoVecData = std::vector<std::string>;
MATCHER_P(IoVecDataMatcher, iovec_data, "") {
  for (const std::string& item : iovec_data) {
    std::string data{reinterpret_cast<const char*>(arg->iov_base),
                     arg->iov_len};
    if (data != item)
      return false;
    arg++;
  }
  return true;
}

MATCHER_P(FileHandleMatcher, value, "") { return arg.Get() == value; }
MATCHER_P(ChannelHandleMatcher, value, "") { return arg.value() == value; }

enum : int {
  kTestPid = 1,
  kTestTid,
  kTestCid,
  kTestMid,
  kTestEuid,
  kTestEgid,
  kTestOp,
};

class MockService : public Service {
 public:
  using Service::Service;
  MOCK_METHOD1(OnChannelOpen, std::shared_ptr<Channel>(Message& message));
  MOCK_METHOD2(OnChannelClose,
               void(Message& message, const std::shared_ptr<Channel>& channel));
  MOCK_METHOD1(HandleMessage, Status<void>(Message& message));
  MOCK_METHOD1(HandleImpulse, void(Message& impulse));
  MOCK_METHOD0(OnSysPropChange, void());
  MOCK_METHOD1(DumpState, std::string(size_t max_length));
};

class ServiceTest : public testing::Test {
 public:
  ServiceTest() {
    auto endpoint = std::make_unique<testing::StrictMock<MockEndpoint>>();
    EXPECT_CALL(*endpoint, SetService(_))
        .Times(2)
        .WillRepeatedly(Return(Status<void>{}));
    service_ = std::make_shared<MockService>("MockSvc", std::move(endpoint));
  }

  MockEndpoint* endpoint() {
    return static_cast<MockEndpoint*>(service_->endpoint());
  }

  void SetupMessageInfo(MessageInfo* info, int32_t op, bool impulse = false) {
    info->pid = kTestPid;
    info->tid = kTestTid;
    info->cid = kTestCid;
    info->mid = impulse ? Message::IMPULSE_MESSAGE_ID : kTestMid;
    info->euid = kTestEuid;
    info->egid = kTestEgid;
    info->op = op;
    info->flags = 0;
    info->service = service_.get();
    info->channel = nullptr;
    info->send_len = 0;
    info->recv_len = 0;
    info->fd_count = 0;
    memset(info->impulse, 0, sizeof(info->impulse));
  }

  void SetupMessageInfoAndDefaultExpectations(MessageInfo* info, int32_t op,
                                              bool impulse = false) {
    SetupMessageInfo(info, op, impulse);
    EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
    EXPECT_CALL(*endpoint(), FreeMessageState(kState));
  }

  void ExpectDefaultHandleMessage() {
    EXPECT_CALL(*endpoint(), MessageReply(_, -EOPNOTSUPP))
        .WillOnce(Return(Status<void>{}));
  }

  std::shared_ptr<MockService> service_;
  void* kState = IntToPtr(123456);
};

class ServiceMessageTest : public ServiceTest {
 public:
  ServiceMessageTest() {
    MessageInfo info;
    SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
    message_ = std::make_unique<Message>(info);
  }

  std::unique_ptr<Message> message_;
};

}  // anonymous namespace

///////////////////////////////////////////////////////////////////////////////
// Service class tests
///////////////////////////////////////////////////////////////////////////////

TEST_F(ServiceTest, IsInitialized) {
  EXPECT_TRUE(service_->IsInitialized());
  service_ = std::make_shared<MockService>("MockSvc2", nullptr);
  EXPECT_FALSE(service_->IsInitialized());
}

TEST_F(ServiceTest, ConstructMessage) {
  MessageInfo info;
  SetupMessageInfo(&info, kTestOp);
  auto test_channel = std::make_shared<Channel>();
  info.channel = test_channel.get();
  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));

  Message message{info};

  EXPECT_FALSE(message.IsImpulse());
  EXPECT_EQ(kTestPid, message.GetProcessId());
  EXPECT_EQ(kTestTid, message.GetThreadId());
  EXPECT_EQ(kTestCid, message.GetChannelId());
  EXPECT_EQ(kTestMid, message.GetMessageId());
  EXPECT_EQ((unsigned) kTestEuid, message.GetEffectiveUserId());
  EXPECT_EQ((unsigned) kTestEgid, message.GetEffectiveGroupId());
  EXPECT_EQ(kTestOp, message.GetOp());
  EXPECT_EQ(service_, message.GetService());
  EXPECT_EQ(test_channel, message.GetChannel());
  EXPECT_FALSE(message.replied());
  EXPECT_FALSE(message.IsChannelExpired());
  EXPECT_FALSE(message.IsServiceExpired());
  EXPECT_EQ(kState, message.GetState());

  ExpectDefaultHandleMessage();
  EXPECT_CALL(*endpoint(), FreeMessageState(kState));
}

TEST_F(ServiceTest, ConstructImpulseMessage) {
  MessageInfo info;
  SetupMessageInfo(&info, kTestOp, true);
  auto test_channel = std::make_shared<Channel>();
  info.channel = test_channel.get();
  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));

  Message message{info};

  EXPECT_TRUE(message.IsImpulse());
  EXPECT_EQ(kTestOp, message.GetOp());
  EXPECT_EQ(service_, message.GetService());
  EXPECT_EQ(test_channel, message.GetChannel());
  EXPECT_TRUE(message.replied());
  EXPECT_FALSE(message.IsChannelExpired());
  EXPECT_FALSE(message.IsServiceExpired());

  // DefaultHandleMessage should not be called here.
  EXPECT_CALL(*endpoint(), FreeMessageState(nullptr));
}

TEST_F(ServiceTest, HandleMessageChannelOpen) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info,
                                         android::pdx::opcodes::CHANNEL_OPEN);
  Message message{info};

  auto channel = std::make_shared<Channel>();
  EXPECT_CALL(*service_, OnChannelOpen(Ref(message))).WillOnce(Return(channel));
  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, channel.get()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageChannelClose) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info,
                                         android::pdx::opcodes::CHANNEL_CLOSE);
  auto channel = std::make_shared<Channel>();
  info.channel = channel.get();
  Message message{info};

  EXPECT_CALL(*service_, OnChannelClose(Ref(message), channel));
  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, nullptr))
      .WillOnce(Return(Status<void>{}));
  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageOnSysPropChange) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(
      &info, android::pdx::opcodes::REPORT_SYSPROP_CHANGE);
  Message message{info};

  EXPECT_CALL(*service_, OnSysPropChange());
  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageOnDumpState) {
  const size_t kRecvBufSize = 1000;
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info,
                                         android::pdx::opcodes::DUMP_STATE);
  info.recv_len = kRecvBufSize;
  Message message{info};

  const std::string kReply = "foo";
  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
  EXPECT_CALL(
      *endpoint(),
      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
      .WillOnce(Return(kReply.size()));
  EXPECT_CALL(*endpoint(), MessageReply(&message, kReply.size()))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageOnDumpStateTooLarge) {
  const size_t kRecvBufSize = 3;
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info,
                                         android::pdx::opcodes::DUMP_STATE);
  info.recv_len = kRecvBufSize;
  Message message{info};

  const std::string kReply = "0123456789";
  const std::string kActualReply = kReply.substr(0, kRecvBufSize);
  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
  EXPECT_CALL(
      *endpoint(),
      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kActualReply}), 1))
      .WillOnce(Return(kActualReply.size()));
  EXPECT_CALL(*endpoint(), MessageReply(&message, kActualReply.size()))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageOnDumpStateFail) {
  const size_t kRecvBufSize = 1000;
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info,
                                         android::pdx::opcodes::DUMP_STATE);
  info.recv_len = kRecvBufSize;
  Message message{info};

  const std::string kReply = "foo";
  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
  EXPECT_CALL(
      *endpoint(),
      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
      .WillOnce(Return(1));
  EXPECT_CALL(*endpoint(), MessageReply(&message, -EIO))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, HandleMessageCustom) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
  Message message{info};

  EXPECT_CALL(*endpoint(), MessageReply(&message, -EOPNOTSUPP))
      .WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->Service::HandleMessage(message));
}

TEST_F(ServiceTest, ReplyMessageWithoutService) {
  MessageInfo info;
  SetupMessageInfo(&info, kTestOp);
  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));

  Message message{info};

  EXPECT_FALSE(message.IsServiceExpired());
  service_.reset();
  EXPECT_TRUE(message.IsServiceExpired());

  EXPECT_EQ(EINVAL, message.Reply(12).error());
}

TEST_F(ServiceTest, ReceiveAndDispatchMessage) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
  ExpectDefaultHandleMessage();

  auto on_receive = [&info](Message* message) -> Status<void> {
    *message = Message{info};
    return {};
  };
  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
  EXPECT_CALL(*service_, HandleMessage(_)).WillOnce(Return(Status<void>{}));

  EXPECT_TRUE(service_->ReceiveAndDispatch());
}

TEST_F(ServiceTest, ReceiveAndDispatchImpulse) {
  MessageInfo info;
  SetupMessageInfoAndDefaultExpectations(&info, kTestOp, true);

  auto on_receive = [&info](Message* message) -> Status<void> {
    *message = Message{info};
    return {};
  };
  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
  EXPECT_CALL(*service_, HandleImpulse(_));

  EXPECT_TRUE(service_->ReceiveAndDispatch());
}

TEST_F(ServiceTest, Cancel) {
  EXPECT_CALL(*endpoint(), Cancel()).WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(service_->Cancel());
}

///////////////////////////////////////////////////////////////////////////////
// Message class tests
///////////////////////////////////////////////////////////////////////////////

TEST_F(ServiceMessageTest, Reply) {
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
      .WillOnce(Return(Status<void>{}));
  EXPECT_FALSE(message_->replied());
  EXPECT_TRUE(message_->Reply(12));
  EXPECT_TRUE(message_->replied());

  EXPECT_EQ(EINVAL, message_->Reply(12).error());  // Already replied.
}

TEST_F(ServiceMessageTest, ReplyFail) {
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(EIO, message_->Reply(12).error());

  ExpectDefaultHandleMessage();
}

TEST_F(ServiceMessageTest, ReplyError) {
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -12))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->ReplyError(12));
}

TEST_F(ServiceMessageTest, ReplyFileDescriptor) {
  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), 5))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->ReplyFileDescriptor(5));
}

TEST_F(ServiceMessageTest, ReplyLocalFileHandle) {
  const int kFakeFd = 12345;
  LocalHandle handle{kFakeFd};
  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
  handle.Release();  // Make sure we do not close the fake file descriptor.
}

TEST_F(ServiceMessageTest, ReplyLocalFileHandleError) {
  LocalHandle handle{-EINVAL};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EINVAL))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyBorrowedFileHandle) {
  const int kFakeFd = 12345;
  BorrowedHandle handle{kFakeFd};
  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyBorrowedFileHandleError) {
  BorrowedHandle handle{-EACCES};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EACCES))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyRemoteFileHandle) {
  RemoteHandle handle{123};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), handle.Get()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyRemoteFileHandleError) {
  RemoteHandle handle{-EIO};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EIO))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyLocalChannelHandle) {
  LocalChannelHandle handle{nullptr, 12345};
  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
                               message_.get(), A<const LocalChannelHandle&>()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyBorrowedChannelHandle) {
  BorrowedChannelHandle handle{12345};
  EXPECT_CALL(*endpoint(),
              MessageReplyChannelHandle(message_.get(),
                                        A<const BorrowedChannelHandle&>()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyRemoteChannelHandle) {
  RemoteChannelHandle handle{12345};
  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
                               message_.get(), A<const RemoteChannelHandle&>()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(handle));
}

TEST_F(ServiceMessageTest, ReplyStatusInt) {
  Status<int> status{123};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), status.get()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(status));
}

TEST_F(ServiceMessageTest, ReplyStatusError) {
  Status<int> status{ErrorStatus{EIO}};
  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -status.error()))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->Reply(status));
}

TEST_F(ServiceMessageTest, Read) {
  ExpectDefaultHandleMessage();
  void* const kDataBuffer = IntToPtr(12345);
  const size_t kDataSize = 100;
  EXPECT_CALL(
      *endpoint(),
      ReadMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
      .WillOnce(Return(50))
      .WillOnce(Return(ErrorStatus{EACCES}));
  EXPECT_EQ(50u, message_->Read(kDataBuffer, kDataSize).get());
  EXPECT_EQ(EACCES, message_->Read(kDataBuffer, kDataSize).error());
}

TEST_F(ServiceMessageTest, ReadVector) {
  ExpectDefaultHandleMessage();
  char buffer1[10];
  char buffer2[20];
  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
  EXPECT_CALL(*endpoint(),
              ReadMessageData(
                  message_.get(),
                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
      .WillOnce(Return(30))
      .WillOnce(Return(15))
      .WillOnce(Return(ErrorStatus{EBADF}));
  EXPECT_EQ(30u, message_->ReadVector(vec, 2).get());
  EXPECT_EQ(15u, message_->ReadVector(vec).get());
  EXPECT_EQ(EBADF, message_->ReadVector(vec).error());
}

TEST_F(ServiceMessageTest, Write) {
  ExpectDefaultHandleMessage();
  void* const kDataBuffer = IntToPtr(12345);
  const size_t kDataSize = 100;
  EXPECT_CALL(
      *endpoint(),
      WriteMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
      .WillOnce(Return(50))
      .WillOnce(Return(ErrorStatus{EBADMSG}));
  EXPECT_EQ(50u, message_->Write(kDataBuffer, kDataSize).get());
  EXPECT_EQ(EBADMSG, message_->Write(kDataBuffer, kDataSize).error());
}

TEST_F(ServiceMessageTest, WriteVector) {
  ExpectDefaultHandleMessage();
  char buffer1[10];
  char buffer2[20];
  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
  EXPECT_CALL(*endpoint(),
              WriteMessageData(
                  message_.get(),
                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
      .WillOnce(Return(30))
      .WillOnce(Return(15))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(30u, message_->WriteVector(vec, 2).get());
  EXPECT_EQ(15u, message_->WriteVector(vec).get());
  EXPECT_EQ(EIO, message_->WriteVector(vec, 2).error());
}

TEST_F(ServiceMessageTest, PushLocalFileHandle) {
  ExpectDefaultHandleMessage();
  const int kFakeFd = 12345;
  LocalHandle handle{kFakeFd};
  EXPECT_CALL(*endpoint(),
              PushFileHandle(message_.get(), Matcher<const LocalHandle&>(
                                                 FileHandleMatcher(kFakeFd))))
      .WillOnce(Return(12))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(12, message_->PushFileHandle(handle).get());
  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
  handle.Release();  // Make sure we do not close the fake file descriptor.
}

TEST_F(ServiceMessageTest, PushBorrowedFileHandle) {
  ExpectDefaultHandleMessage();
  const int kFakeFd = 12345;
  BorrowedHandle handle{kFakeFd};
  EXPECT_CALL(*endpoint(),
              PushFileHandle(message_.get(), Matcher<const BorrowedHandle&>(
                                                 FileHandleMatcher(kFakeFd))))
      .WillOnce(Return(13))
      .WillOnce(Return(ErrorStatus{EACCES}));
  EXPECT_EQ(13, message_->PushFileHandle(handle).get());
  EXPECT_EQ(EACCES, message_->PushFileHandle(handle).error());
}

TEST_F(ServiceMessageTest, PushRemoteFileHandle) {
  ExpectDefaultHandleMessage();
  const int kFakeFd = 12345;
  RemoteHandle handle{kFakeFd};
  EXPECT_CALL(*endpoint(),
              PushFileHandle(message_.get(), Matcher<const RemoteHandle&>(
                                                 FileHandleMatcher(kFakeFd))))
      .WillOnce(Return(kFakeFd))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(kFakeFd, message_->PushFileHandle(handle).get());
  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
}

TEST_F(ServiceMessageTest, PushLocalChannelHandle) {
  ExpectDefaultHandleMessage();
  int32_t kValue = 12345;
  LocalChannelHandle handle{nullptr, kValue};
  EXPECT_CALL(*endpoint(), PushChannelHandle(message_.get(),
                                             Matcher<const LocalChannelHandle&>(
                                                 ChannelHandleMatcher(kValue))))
      .WillOnce(Return(7))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(7, message_->PushChannelHandle(handle).get());
  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
}

TEST_F(ServiceMessageTest, PushBorrowedChannelHandle) {
  ExpectDefaultHandleMessage();
  int32_t kValue = 12345;
  BorrowedChannelHandle handle{kValue};
  EXPECT_CALL(
      *endpoint(),
      PushChannelHandle(message_.get(), Matcher<const BorrowedChannelHandle&>(
                                            ChannelHandleMatcher(kValue))))
      .WillOnce(Return(8))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(8, message_->PushChannelHandle(handle).get());
  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
}

TEST_F(ServiceMessageTest, PushRemoteChannelHandle) {
  ExpectDefaultHandleMessage();
  int32_t kValue = 12345;
  RemoteChannelHandle handle{kValue};
  EXPECT_CALL(
      *endpoint(),
      PushChannelHandle(message_.get(), Matcher<const RemoteChannelHandle&>(
                                            ChannelHandleMatcher(kValue))))
      .WillOnce(Return(kValue))
      .WillOnce(Return(ErrorStatus{EIO}));
  EXPECT_EQ(kValue, message_->PushChannelHandle(handle).get());
  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
}

TEST_F(ServiceMessageTest, GetFileHandle) {
  ExpectDefaultHandleMessage();
  auto make_file_handle = [](FileReference ref) { return LocalHandle{ref}; };
  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
      .WillOnce(WithArg<1>(Invoke(make_file_handle)));
  LocalHandle handle;
  FileReference kRef = 12345;
  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
  EXPECT_EQ(kRef, handle.Get());
  handle.Release();  // Make sure we do not close the fake file descriptor.
}

TEST_F(ServiceMessageTest, GetFileHandleInvalid) {
  ExpectDefaultHandleMessage();
  LocalHandle handle;
  FileReference kRef = -12;
  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
  EXPECT_EQ(kRef, handle.Get());
}

TEST_F(ServiceMessageTest, GetFileHandleError) {
  ExpectDefaultHandleMessage();
  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
      .WillOnce(WithoutArgs(Invoke([] { return LocalHandle{-EIO}; })));
  LocalHandle handle;
  FileReference kRef = 12345;
  EXPECT_FALSE(message_->GetFileHandle(kRef, &handle));
  EXPECT_EQ(-EIO, handle.Get());
}

TEST_F(ServiceMessageTest, GetChannelHandle) {
  ExpectDefaultHandleMessage();
  auto make_channel_handle = [](ChannelReference ref) {
    return LocalChannelHandle{nullptr, ref};
  };
  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
      .WillOnce(WithArg<1>(Invoke(make_channel_handle)));
  LocalChannelHandle handle;
  ChannelReference kRef = 12345;
  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
  EXPECT_EQ(kRef, handle.value());
}

TEST_F(ServiceMessageTest, GetChannelHandleInvalid) {
  ExpectDefaultHandleMessage();
  LocalChannelHandle handle;
  ChannelReference kRef = -12;
  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
  EXPECT_EQ(-12, handle.value());
}

TEST_F(ServiceMessageTest, GetChannelHandleError) {
  ExpectDefaultHandleMessage();
  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
      .WillOnce(WithoutArgs(Invoke([] {
        return LocalChannelHandle{nullptr, -EIO};
      })));
  LocalChannelHandle handle;
  ChannelReference kRef = 12345;
  EXPECT_FALSE(message_->GetChannelHandle(kRef, &handle));
  EXPECT_EQ(-EIO, handle.value());
}

TEST_F(ServiceMessageTest, ModifyChannelEvents) {
  ExpectDefaultHandleMessage();
  int kClearMask = 1;
  int kSetMask = 2;
  EXPECT_CALL(*endpoint(), ModifyChannelEvents(kTestCid, kClearMask, kSetMask))
      .WillOnce(Return(Status<void>{}));
  EXPECT_TRUE(message_->ModifyChannelEvents(kClearMask, kSetMask));
}

TEST_F(ServiceMessageTest, PushChannelSameService) {
  ExpectDefaultHandleMessage();
  int kFlags = 123;
  int32_t kValue = 12;
  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
                      Return(ByMove(RemoteChannelHandle{kValue}))));
  int channel_id = -1;
  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
  ASSERT_TRUE(status);
  EXPECT_EQ(kValue, status.get().value());
  EXPECT_EQ(kTestCid, channel_id);
}

TEST_F(ServiceMessageTest, PushChannelFailure) {
  ExpectDefaultHandleMessage();
  int kFlags = 123;
  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
      .WillOnce(Return(ByMove(ErrorStatus{EIO})));
  int channel_id = -1;
  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
  ASSERT_FALSE(status);
  EXPECT_EQ(EIO, status.error());
}

TEST_F(ServiceMessageTest, PushChannelDifferentService) {
  ExpectDefaultHandleMessage();
  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
  EXPECT_CALL(*endpoint2, SetService(_))
      .Times(2)
      .WillRepeatedly(Return(Status<void>{}));
  auto service2 =
      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));

  int kFlags = 123;
  int32_t kValue = 12;
  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
              PushChannel(message_.get(), kFlags, nullptr, _))
      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
                      Return(ByMove(RemoteChannelHandle{kValue}))));
  int channel_id = -1;
  auto status =
      message_->PushChannel(service2.get(), kFlags, nullptr, &channel_id);
  ASSERT_TRUE(status);
  EXPECT_EQ(kValue, status.get().value());
  EXPECT_EQ(kTestCid, channel_id);
}

TEST_F(ServiceMessageTest, CheckChannelSameService) {
  ExpectDefaultHandleMessage();

  auto test_channel = std::make_shared<Channel>();
  ChannelReference kRef = 123;
  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
  std::shared_ptr<Channel> channel;
  auto status = message_->CheckChannel(kRef, &channel);
  ASSERT_TRUE(status);
  EXPECT_EQ(kTestCid, status.get());
  EXPECT_EQ(test_channel, channel);
}

TEST_F(ServiceMessageTest, CheckChannelFailure) {
  ExpectDefaultHandleMessage();
  ChannelReference kRef = 123;
  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
      .WillOnce(Return(ByMove(ErrorStatus{EOPNOTSUPP})));
  std::shared_ptr<Channel> channel;
  auto status = message_->CheckChannel(kRef, &channel);
  ASSERT_FALSE(status);
  EXPECT_EQ(EOPNOTSUPP, status.error());
}

TEST_F(ServiceMessageTest, CheckChannelDifferentService) {
  ExpectDefaultHandleMessage();
  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
  EXPECT_CALL(*endpoint2, SetService(_))
      .Times(2)
      .WillRepeatedly(Return(Status<void>{}));
  auto service2 =
      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));

  auto test_channel = std::make_shared<Channel>();
  ChannelReference kRef = 123;
  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
              CheckChannel(message_.get(), kRef, _))
      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
  std::shared_ptr<Channel> channel;
  auto status = message_->CheckChannel(service2.get(), kRef, &channel);
  ASSERT_TRUE(status);
  EXPECT_EQ(kTestCid, status.get());
  EXPECT_EQ(test_channel, channel);
}
