// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <object/message_packet.h>

#include <ktl/unique_ptr.h>
#include <lib/unittest/unittest.h>
#include <lib/unittest/user_memory.h>
#include <lib/user_copy/user_ptr.h>

namespace {

using testing::UserMemory;

// Create a MessagePacket and call CopyDataTo.
static bool create() {
    BEGIN_TEST;
    constexpr size_t kSize = 62234;
    ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kSize);
    auto mem_in = make_user_in_ptr(mem->in());
    auto mem_out = make_user_out_ptr(mem->out());

    fbl::AllocChecker ac;
    auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    memset(buf.get(), 'A', kSize);
    ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kSize), "");

    constexpr uint32_t kNumHandles = 64;
    MessagePacketPtr mp;
    EXPECT_EQ(ZX_OK, MessagePacket::Create(mem_in, kSize, kNumHandles, &mp), "");
    ASSERT_EQ(kSize, mp->data_size(), "");
    EXPECT_EQ(kNumHandles, mp->num_handles(), "");
    EXPECT_NE(0U, mp->get_txid(), "");

    auto result_buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    ASSERT_EQ(ZX_OK, mp->CopyDataTo(mem_out), "");
    ASSERT_EQ(ZX_OK, mem_in.copy_array_from_user(result_buf.get(), kSize), "");
    EXPECT_EQ(0, memcmp(buf.get(), result_buf.get(), kSize), "");
    END_TEST;
}

// Create a MessagePacket via void* and call CopyDataTo.
static bool create_void_star() {
    BEGIN_TEST;
    constexpr size_t kSize = 4;
    ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kSize);
    auto mem_in = make_user_in_ptr(mem->in());
    auto mem_out = make_user_out_ptr(mem->out());

    fbl::AllocChecker ac;
    auto in_buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    memset(in_buf.get(), 'B', kSize);
    void* in = in_buf.get();

    constexpr uint32_t kNumHandles = 0;
    MessagePacketPtr mp;
    EXPECT_EQ(ZX_OK, MessagePacket::Create(in, kSize, kNumHandles, &mp), "");
    ASSERT_EQ(kSize, mp->data_size(), "");
    EXPECT_EQ(kNumHandles, mp->num_handles(), "");
    EXPECT_NE(0U, mp->get_txid(), "");

    auto result_buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    ASSERT_EQ(ZX_OK, mp->CopyDataTo(mem_out), "");
    ASSERT_EQ(ZX_OK, mem_in.copy_array_from_user(result_buf.get(), kSize), "");
    EXPECT_EQ(0, memcmp(in_buf.get(), result_buf.get(), kSize), "");
    END_TEST;
}

// Create a MessagePacket with zero-length data.
static bool create_zero() {
    BEGIN_TEST;
    ktl::unique_ptr<UserMemory> mem = UserMemory::Create(1);
    auto mem_in = make_user_in_ptr(mem->in());
    auto mem_out = make_user_out_ptr(mem->out());

    MessagePacketPtr mp;
    EXPECT_EQ(ZX_OK, MessagePacket::Create(mem_in, 0, 0, &mp), "");
    ASSERT_EQ(0U, mp->data_size(), "");
    EXPECT_EQ(0U, mp->num_handles(), "");
    EXPECT_EQ(0U, mp->get_txid(),"");

    ASSERT_EQ(ZX_OK, mp->CopyDataTo(mem_out), "");
    END_TEST;
}

// Attempt to create a MessagePacket with too many handles.
static bool create_too_many_handles() {
    BEGIN_TEST;
    ktl::unique_ptr<UserMemory> mem = UserMemory::Create(1);
    auto mem_in = make_user_in_ptr(mem->in());

    MessagePacketPtr mp;
    EXPECT_EQ(ZX_ERR_OUT_OF_RANGE, MessagePacket::Create(mem_in, 1, 65, &mp), "");
    END_TEST;
}

// Attempt to create a MessagePacket from memory that's not part of userspace.
static bool create_bad_mem() {
    BEGIN_TEST;
    constexpr size_t kSize = 64;

    fbl::AllocChecker ac;
    auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    memset(buf.get(), 'C', kSize);
    auto in = make_user_in_ptr(static_cast<const void*>(buf.get()));

    constexpr uint32_t kNumHandles = 0;
    MessagePacketPtr mp;
    EXPECT_EQ(ZX_ERR_INVALID_ARGS, MessagePacket::Create(in, kSize, kNumHandles, &mp), "");
    END_TEST;
}

// Attempt to copy a MessagePacket to memory that's not part of userspace.
static bool copy_bad_mem() {
    BEGIN_TEST;
    constexpr size_t kSize = 64;
    ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kSize);
    auto mem_in = make_user_in_ptr(mem->in());
    auto mem_out = make_user_out_ptr(mem->out());

    fbl::AllocChecker ac;
    auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
    ASSERT_TRUE(ac.check(), "");
    memset(buf.get(), 'D', kSize);
    ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kSize), "");

    constexpr uint32_t kNumHandles = 0;
    MessagePacketPtr mp;
    EXPECT_EQ(ZX_OK, MessagePacket::Create(mem_in, kSize, kNumHandles, &mp), "");

    auto out = make_user_out_ptr(static_cast<void*>(buf.get()));
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, mp->CopyDataTo(out), "");
    END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(message_packet_tests)
UNITTEST("create", create)
UNITTEST("create_void_star", create_void_star)
UNITTEST("create_zero", create_zero)
UNITTEST("create_too_many_handles", create_too_many_handles)
UNITTEST("create_bad_mem", create_bad_mem)
UNITTEST("copy_bad_mem", copy_bad_mem)
UNITTEST_END_TESTCASE(message_packet_tests, "message_packet", "MessagePacket tests");
