// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/mach/mach_message.h"

#include <unistd.h>

#include <tuple>

#include "base/apple/scoped_mach_port.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "util/mach/mach_extensions.h"
#include "util/misc/implicit_cast.h"

namespace crashpad {
namespace test {
namespace {

TEST(MachMessage, MachMessageDeadlineFromTimeout) {
  MachMessageDeadline deadline_0 =
      MachMessageDeadlineFromTimeout(kMachMessageTimeoutNonblocking);
  EXPECT_EQ(deadline_0, kMachMessageDeadlineNonblocking);

  deadline_0 =
      MachMessageDeadlineFromTimeout(kMachMessageTimeoutWaitIndefinitely);
  EXPECT_EQ(deadline_0, kMachMessageDeadlineWaitIndefinitely);

  deadline_0 = MachMessageDeadlineFromTimeout(1);
  MachMessageDeadline deadline_1 = MachMessageDeadlineFromTimeout(100);

  EXPECT_NE(deadline_0, kMachMessageDeadlineNonblocking);
  EXPECT_NE(deadline_0, kMachMessageDeadlineWaitIndefinitely);
  EXPECT_NE(deadline_1, kMachMessageDeadlineNonblocking);
  EXPECT_NE(deadline_1, kMachMessageDeadlineWaitIndefinitely);
  EXPECT_GE(deadline_1, deadline_0);
}

TEST(MachMessage, PrepareMIGReplyFromRequest_SetMIGReplyError) {
  mach_msg_header_t request;
  request.msgh_bits =
      MACH_MSGH_BITS_COMPLEX |
      MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, MACH_MSG_TYPE_PORT_SEND);
  request.msgh_size = 64;
  request.msgh_remote_port = 0x01234567;
  request.msgh_local_port = 0x89abcdef;
  request.msgh_reserved = 0xa5a5a5a5;
  request.msgh_id = 1011;

  mig_reply_error_t reply;

  // PrepareMIGReplyFromRequest() doesn’t touch this field.
  reply.RetCode = MIG_TYPE_ERROR;

  PrepareMIGReplyFromRequest(&request, &reply.Head);

  EXPECT_EQ(reply.Head.msgh_bits,
            implicit_cast<mach_msg_bits_t>(
                MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0)));
  EXPECT_EQ(reply.Head.msgh_size, sizeof(reply));
  EXPECT_EQ(reply.Head.msgh_remote_port, request.msgh_remote_port);
  EXPECT_EQ(reply.Head.msgh_local_port, kMachPortNull);
  EXPECT_EQ(reply.Head.msgh_reserved, 0u);
  EXPECT_EQ(reply.Head.msgh_id, 1111);
  EXPECT_EQ(reply.NDR.mig_vers, NDR_record.mig_vers);
  EXPECT_EQ(reply.NDR.if_vers, NDR_record.if_vers);
  EXPECT_EQ(reply.NDR.reserved1, NDR_record.reserved1);
  EXPECT_EQ(reply.NDR.mig_encoding, NDR_record.mig_encoding);
  EXPECT_EQ(reply.NDR.int_rep, NDR_record.int_rep);
  EXPECT_EQ(reply.NDR.char_rep, NDR_record.char_rep);
  EXPECT_EQ(reply.NDR.float_rep, NDR_record.float_rep);
  EXPECT_EQ(reply.NDR.reserved2, NDR_record.reserved2);
  EXPECT_EQ(reply.RetCode, MIG_TYPE_ERROR);

  SetMIGReplyError(&reply.Head, MIG_BAD_ID);

  EXPECT_EQ(reply.RetCode, MIG_BAD_ID);
}

TEST(MachMessage, MachMessageTrailerFromHeader) {
  mach_msg_empty_t empty;
  empty.send.header.msgh_size = sizeof(mach_msg_empty_send_t);
  EXPECT_EQ(MachMessageTrailerFromHeader(&empty.rcv.header),
            &empty.rcv.trailer);

  struct TestSendMessage : public mach_msg_header_t {
    uint8_t data[126];
  };
  struct TestReceiveMessage : public TestSendMessage {
    mach_msg_trailer_t trailer;
  };
  union TestMessage {
    TestSendMessage send;
    TestReceiveMessage receive;
  };

  TestMessage test;
  test.send.msgh_size = sizeof(TestSendMessage);
  EXPECT_EQ(MachMessageTrailerFromHeader(&test.receive), &test.receive.trailer);
}

TEST(MachMessage, MachMessageDestroyReceivedPort) {
  mach_port_t port = NewMachPort(MACH_PORT_RIGHT_RECEIVE);
  ASSERT_NE(port, kMachPortNull);
  EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_RECEIVE));

  base::apple::ScopedMachReceiveRight receive(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  mach_msg_type_name_t right_type;
  kern_return_t kr = mach_port_extract_right(mach_task_self(),
                                             receive.get(),
                                             MACH_MSG_TYPE_MAKE_SEND,
                                             &port,
                                             &right_type);
  ASSERT_EQ(kr, KERN_SUCCESS)
      << MachErrorMessage(kr, "mach_port_extract_right");
  ASSERT_EQ(port, receive);
  ASSERT_EQ(right_type,
            implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND));
  EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND));

  kr = mach_port_extract_right(mach_task_self(),
                               receive.get(),
                               MACH_MSG_TYPE_MAKE_SEND_ONCE,
                               &port,
                               &right_type);
  ASSERT_EQ(kr, KERN_SUCCESS)
      << MachErrorMessage(kr, "mach_port_extract_right");
  ASSERT_NE(port, kMachPortNull);
  EXPECT_NE(port, receive);
  ASSERT_EQ(right_type,
            implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND_ONCE));
  EXPECT_TRUE(
      MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND_ONCE));

  kr = mach_port_extract_right(mach_task_self(),
                               receive.get(),
                               MACH_MSG_TYPE_MAKE_SEND,
                               &port,
                               &right_type);
  ASSERT_EQ(kr, KERN_SUCCESS)
      << MachErrorMessage(kr, "mach_port_extract_right");
  ASSERT_EQ(port, receive);
  ASSERT_EQ(right_type,
            implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND));
  EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_RECEIVE));
  std::ignore = receive.release();
  EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND));
}

#if BUILDFLAG(IS_MAC)

TEST(MachMessage, AuditPIDFromMachMessageTrailer) {
  base::apple::ScopedMachReceiveRight port(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_NE(port, kMachPortNull);

  mach_msg_empty_send_t send = {};
  send.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND_ONCE, 0);
  send.header.msgh_size = sizeof(send);
  send.header.msgh_remote_port = port.get();
  mach_msg_return_t mr =
      MachMessageWithDeadline(&send.header,
                              MACH_SEND_MSG,
                              0,
                              MACH_PORT_NULL,
                              kMachMessageDeadlineNonblocking,
                              MACH_PORT_NULL,
                              false);
  ASSERT_EQ(mr, MACH_MSG_SUCCESS)
      << MachErrorMessage(mr, "MachMessageWithDeadline send");

  struct EmptyReceiveMessageWithAuditTrailer : public mach_msg_empty_send_t {
    union {
      mach_msg_trailer_t trailer;
      mach_msg_audit_trailer_t audit_trailer;
    };
  };

  EmptyReceiveMessageWithAuditTrailer receive;
  mr = MachMessageWithDeadline(&receive.header,
                               MACH_RCV_MSG | kMachMessageReceiveAuditTrailer,
                               sizeof(receive),
                               port.get(),
                               kMachMessageDeadlineNonblocking,
                               MACH_PORT_NULL,
                               false);
  ASSERT_EQ(mr, MACH_MSG_SUCCESS)
      << MachErrorMessage(mr, "MachMessageWithDeadline receive");

  EXPECT_EQ(AuditPIDFromMachMessageTrailer(&receive.trailer), getpid());
}

#endif  // BUILDFLAG(IS_MAC)

}  // namespace
}  // namespace test
}  // namespace crashpad
