// 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/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 Buffers required.
  bc = BufferChain::Alloc(BufferChain::kContig + 1);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 2u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  // Many Buffers required.
  bc = BufferChain::Alloc(10000 * BufferChain::kRawDataSize);
  ASSERT_FALSE(bc->buffers()->is_empty());
  ASSERT_EQ(bc->buffers()->size_slow(), 1u + 10000u);
  ASSERT_NE(bc, nullptr);
  BufferChain::Free(bc);

  END_TEST;
}

static bool copy_in_copy_out() {
  BEGIN_TEST;

  constexpr size_t kSize = BufferChain::kContig + 2 * BufferChain::kRawDataSize;
  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 = make_user_in_ptr(mem->in());
  auto mem_out = make_user_out_ptr(mem->out());

  BufferChain* bc = BufferChain::Alloc(kSize);
  ASSERT_NE(nullptr, bc);
  ASSERT_FALSE(bc->buffers()->is_empty());

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

  // Verify it.
  ASSERT_EQ(3u, bc->buffers()->size_slow());
  for (auto& b : *bc->buffers()) {
    char* data = b.data();
    for (size_t i = 0; i < b.size(); ++i) {
      ASSERT_EQ('A', data[i]);
    }
  }

  // Write a chunk of 'B' straddling all three buffers.
  memset(buf.get(), 'B', kSize);
  ASSERT_EQ(ZX_OK, mem_out.copy_array_to_user(buf.get(), kSize));
  size_t offset = BufferChain::kContig - 1;
  size_t size = BufferChain::kRawDataSize + 2;
  ASSERT_EQ(ZX_OK, bc->CopyIn(mem_in, offset, size));

  // Verify it.
  auto iter = bc->buffers()->begin();
  for (size_t i = 0; i < offset; ++i) {
    char* data = iter->data();
    ASSERT_EQ('A', data[i]);
  }
  ASSERT_EQ('B', *(iter->data() + offset));
  ++iter;
  for (size_t i = 0; i < BufferChain::kRawDataSize; ++i) {
    char* data = iter->data();
    ASSERT_EQ('B', data[i]);
  }
  ++iter;
  ASSERT_EQ('B', *iter->data());
  for (size_t i = 1; i < BufferChain::kRawDataSize; ++i) {
    char* data = iter->data();
    EXPECT_EQ('A', 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 = 0;
  for (size_t i = 0; i < offset; ++i) {
    ASSERT_EQ('A', buf[index++]);
  }
  EXPECT_EQ('B', buf[index++]);
  for (size_t i = 0; i < BufferChain::kRawDataSize; ++i) {
    ASSERT_EQ('B', buf[index++]);
  }
  ASSERT_EQ('B', buf[index++]);
  for (size_t i = 1; i < BufferChain::kRawDataSize; ++i) {
    EXPECT_EQ('A', buf[index++]);
  }

  BufferChain::Free(bc);

  END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(buffer_chain_tests)
UNITTEST("alloc_free_basic", alloc_free_basic)
UNITTEST("copy_in_copy_out", copy_in_copy_out)
UNITTEST_END_TESTCASE(buffer_chain_tests, "buffer_chain", "BufferChain tests");
