// 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 <lib/fit/defer.h>
#include <lib/unittest/unittest.h>
#include <lib/unittest/user_memory.h>
#include <lib/user_copy/user_ptr.h>
#include <stdio.h>

#include "object/buffer_chain.h"

namespace {

using testing::UserMemory;

static bool alloc_free_basic() {
  BEGIN_TEST;

  // An empty chain requires one buffer
  BufferChain* bc = BufferChain::Alloc(0);
  ASSERT_NE(bc, nullptr);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u);
  BufferChain::Free(bc);

  // One Buffer is enough to hold one byte.
  bc = BufferChain::Alloc(1);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  // One Buffer is still enough.
  bc = BufferChain::Alloc(BufferChain::kContig);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  // Two pages allocated, only one used for the buffer.
  bc = BufferChain::Alloc(BufferChain::kContig + 1);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  // Several pages allocated, only one used for the buffer.
  bc = BufferChain::Alloc(10000 * BufferChain::kRawDataSize);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  END_TEST;
}

static bool append_copy_out() {
  BEGIN_TEST;

  constexpr size_t kOffset = 24;
  constexpr size_t kFirstCopy = BufferChain::kContig + 8;
  constexpr size_t kSecondCopy = BufferChain::kRawDataSize + 16;
  constexpr size_t kSize = kOffset + kFirstCopy + kSecondCopy;

  fbl::AllocChecker ac;
  auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kSize]);
  ASSERT_TRUE(ac.check());
  ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kSize);
  auto mem_in = mem->user_in<char>();
  auto mem_out = mem->user_out<char>();

  BufferChain* bc = BufferChain::Alloc(kSize);
  ASSERT_NE(nullptr, bc);
  auto free_bc = fit::defer([&bc]() { BufferChain::Free(bc); });
  ASSERT_EQ(1u, bc->buffers()->size_slow());

  bc->Skip(kOffset);

  // Fill the chain with 'A'.
  memset(buf.get(), 'A', kFirstCopy);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kFirstCopy));
  ASSERT_EQ(ZX_OK, bc->Append(mem_in, kFirstCopy));

  // Verify it.
  auto iter = bc->buffers()->begin();
  for (size_t i = kOffset; i < BufferChain::kContig; ++i) {
    ASSERT_EQ('A', iter->data()[i]);
  }
  ++iter;
  for (size_t i = 0; i < kOffset + kFirstCopy - BufferChain::kContig; ++i) {
    ASSERT_EQ('A', iter->data()[i]);
  }

  // Write a chunk of 'B' straddling all three buffers.
  memset(buf.get(), 'B', kSecondCopy);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kSecondCopy));
  ASSERT_EQ(ZX_OK, bc->Append(mem_in, kSecondCopy));

  // Verify it.
  iter = bc->buffers()->begin();
  for (size_t i = kOffset; i < BufferChain::kContig; ++i) {
    ASSERT_EQ('A', iter->data()[i]);
  }
  ++iter;
  for (size_t i = 0; i < kOffset + kFirstCopy - BufferChain::kContig; ++i) {
    ASSERT_EQ('A', iter->data()[i]);
  }
  for (size_t i = kOffset + kFirstCopy - BufferChain::kContig; i < BufferChain::kRawDataSize; ++i) {
    ASSERT_EQ('B', iter->data()[i]);
  }
  ++iter;
  for (size_t i = 0;
       i < kOffset + kFirstCopy + kSecondCopy - BufferChain::kContig - BufferChain::kRawDataSize;
       ++i) {
    if (iter->data()[i] != 'B') {
      ASSERT_EQ(int(i), -1);
    }
    ASSERT_EQ('B', iter->data()[i]);
  }
  ASSERT_TRUE(++iter == bc->buffers()->end());

  // Copy it all out.
  memset(buf.get(), 0, kSize);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kSize));
  ASSERT_EQ(ZX_OK, bc->CopyOut(mem_out, 0, kSize));

  // Verify it.
  memset(buf.get(), 0, kSize);
  ASSERT_EQ(ZX_OK, mem_in.copy_array_from_user(buf.get(), kSize));
  size_t index = kOffset;
  for (size_t i = 0; i < kFirstCopy; ++i) {
    ASSERT_EQ('A', buf[index++]);
  }
  for (size_t i = 0; i < kSecondCopy; ++i) {
    ASSERT_EQ('B', buf[index++]);
  }

  END_TEST;
}

static bool free_unused_pages() {
  BEGIN_TEST;

  constexpr size_t kSize = 8 * PAGE_SIZE;
  constexpr size_t kWriteSize = BufferChain::kContig + 1;

  fbl::AllocChecker ac;
  auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kWriteSize]);
  ASSERT_TRUE(ac.check());
  ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kWriteSize);
  auto mem_in = mem->user_in<char>();
  auto mem_out = mem->user_out<char>();

  BufferChain* bc = BufferChain::Alloc(kSize);
  ASSERT_NE(nullptr, bc);
  auto free_bc = fit::defer([&bc]() { BufferChain::Free(bc); });
  ASSERT_EQ(1u, bc->buffers()->size_slow());

  memset(buf.get(), 0, kWriteSize);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kWriteSize));
  ASSERT_EQ(ZX_OK, bc->Append(mem_in, kWriteSize));

  ASSERT_EQ(2u, bc->buffers()->size_slow());
  bc->FreeUnusedBuffers();
  ASSERT_EQ(2u, bc->buffers()->size_slow());

  END_TEST;
}

static bool append_more_than_allocated() {
  BEGIN_TEST;

  constexpr size_t kAllocSize = 2 * PAGE_SIZE;
  constexpr size_t kWriteSize = 2 * kAllocSize;

  fbl::AllocChecker ac;
  auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kWriteSize]);
  ASSERT_TRUE(ac.check());
  ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kWriteSize);
  auto mem_in = mem->user_in<char>();
  auto mem_out = mem->user_out<char>();

  BufferChain* bc = BufferChain::Alloc(kAllocSize);
  ASSERT_NE(nullptr, bc);
  auto free_bc = fit::defer([&bc]() { BufferChain::Free(bc); });
  ASSERT_EQ(1u, bc->buffers()->size_slow());

  memset(buf.get(), 0, kWriteSize);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kWriteSize));
  ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, bc->Append(mem_in, kWriteSize));

  END_TEST;
}

static bool append_after_fail_fails() {
  BEGIN_TEST;

  constexpr size_t kAllocSize = 2 * PAGE_SIZE;
  constexpr size_t kWriteSize = PAGE_SIZE;

  fbl::AllocChecker ac;
  auto buf = ktl::unique_ptr<char[]>(new (&ac) char[kWriteSize]);
  ASSERT_TRUE(ac.check());
  ktl::unique_ptr<UserMemory> mem = UserMemory::Create(kWriteSize);
  auto mem_in = mem->user_in<char>();
  auto mem_out = mem->user_out<char>();

  BufferChain* bc = BufferChain::Alloc(kAllocSize);
  ASSERT_NE(nullptr, bc);
  auto free_bc = fit::defer([&bc]() { BufferChain::Free(bc); });
  ASSERT_EQ(1u, bc->buffers()->size_slow());

  ASSERT_EQ(ZX_ERR_INVALID_ARGS,
            bc->Append(make_user_in_ptr(static_cast<const char*>(nullptr)), kWriteSize));

  memset(buf.get(), 0, kWriteSize);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kWriteSize));
  ASSERT_EQ(ZX_ERR_OUT_OF_RANGE, bc->Append(mem_in, kWriteSize));

  END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(buffer_chain_tests)
UNITTEST("alloc_free_basic", alloc_free_basic)
UNITTEST("append_copy_out", append_copy_out)
UNITTEST("free_unused_pages", free_unused_pages)
UNITTEST("append_more_than_allocated", append_more_than_allocated)
UNITTEST("append_after_fail_fails", append_after_fail_fails)
UNITTEST_END_TESTCASE(buffer_chain_tests, "buffer_chain", "BufferChain tests")
