// Copyright 2017 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 <fbl/name.h>

namespace {

constexpr char fill = 0x7f;

bool buffer_invariants_hold(const char* buf, size_t size) {
  // The buffer should start with zero or more non-NUL bytes followed
  // by a NUL.
  unsigned int idx = 0;
  while (buf[idx] != 0) {
    idx++;
    if (idx == size) {
      unittest_printf("No NUL byte found\n");
      return false;
    }
  }
  idx++;  // Skip the NUL
  // The rest of the buffer should be filled with the NUL byte
  // to ensure stale data isn't leaked.
  while (idx < size) {
    if (buf[idx] != '\0') {
      unsigned int byte = buf[idx];
      unittest_printf("buf[%u] 0x%02x != 0x00\n", idx, byte);
      return false;
    }
    idx++;
  }
  return true;
}

template <size_t Size>
bool empty_ctor() {
  BEGIN_TEST;

  // Note on |out| sizes: most tests use Size * 2 to ensure the out buffer is
  // more than big enough to read the entire name with room to spare.
  char out[Size * 2];
  memset(out, fill, sizeof(out));

  fbl::Name<Size> name;
  name.get(sizeof(out), out);

  EXPECT_EQ(out[0], 0);
  EXPECT_TRUE(buffer_invariants_hold(out, sizeof(out)));

  END_TEST;
}

template <size_t Size>
bool named_ctor_empty() {
  BEGIN_TEST;

  char out[Size * 2];
  memset(out, fill, sizeof(out));

  fbl::Name<Size> name("", 1);
  name.get(sizeof(out), out);

  EXPECT_EQ(out[0], 0);
  EXPECT_TRUE(buffer_invariants_hold(out, sizeof(out)));

  END_TEST;
}

template <size_t Size>
bool named_ctor_small() {
  BEGIN_TEST;

  char out[Size * 2];
  memset(out, fill, sizeof(out));

  fbl::Name<Size> name("a", 2);
  name.get(sizeof(out), out);

  EXPECT_EQ(out[0], 'a');
  EXPECT_EQ(out[1], 0);
  EXPECT_TRUE(buffer_invariants_hold(out, sizeof(out)));

  END_TEST;
}

template <size_t Size>
bool named_ctor_exact() {
  BEGIN_TEST;

  char out[Size * 2];
  memset(out, fill, sizeof(out));

  char expected_name[Size];
  memset(expected_name, 'z', Size - 1);
  expected_name[Size - 1] = 0;

  fbl::Name<Size> name(expected_name, Size);
  name.get(sizeof(out), out);

  for (size_t idx = 0; idx < Size - 1; ++idx) {
    EXPECT_EQ(out[idx], 'z');
  }
  EXPECT_EQ(out[Size - 1], 0);
  EXPECT_TRUE(buffer_invariants_hold(out, sizeof(out)));

  END_TEST;
}

template <size_t Size>
bool named_ctor_overflow() {
  BEGIN_TEST;

  constexpr size_t overflow_size = 2 * Size;

  char out[overflow_size * 2];
  memset(out, fill, sizeof(out));

  char expected_name[overflow_size];
  memset(expected_name, 'z', overflow_size - 1);
  expected_name[overflow_size - 1] = 0;

  fbl::Name<Size> name(expected_name, overflow_size);
  name.get(sizeof(out), out);

  for (size_t idx = 0; idx < Size - 1; ++idx) {
    EXPECT_EQ(out[idx], 'z');
  }
  EXPECT_EQ(out[Size - 1], 0);
  EXPECT_TRUE(buffer_invariants_hold(out, sizeof(out)));

  END_TEST;
}

template <size_t Size>
bool zero_sized_output_buffer() {
  BEGIN_TEST;

  // Neither of these bytes should be touched.
  char out[2] = {fill, fill};

  fbl::Name<Size> name("a", 2);
  name.get(0, out);

  EXPECT_EQ(out[0], fill);
  EXPECT_EQ(out[1], fill);

  END_TEST;
}

template <size_t NameSize, size_t OutSize>
bool output_buffer_size() {
  static_assert(OutSize > 0, "");  // |OutSize - 1| below would fail.

  BEGIN_TEST;

  // Longest name possible.
  char expected_name[NameSize];
  memset(expected_name, 'z', NameSize - 1);
  expected_name[NameSize - 1] = 0;

  char out[OutSize + 2];  // Extra fill at the end.
  memset(out, fill, sizeof(out));

  fbl::Name<NameSize> name(expected_name, sizeof(expected_name));
  name.get(OutSize, out);

  // Check that the name fits in the size we passed to Name::get().
  for (size_t idx = 0; idx < OutSize - 1; ++idx) {
    char msg[32];
    snprintf(msg, sizeof(msg), "idx=%zu", idx);
    EXPECT_EQ(out[idx], 'z', msg);
  }
  EXPECT_EQ(out[OutSize - 1], 0);

  // Check that the extra fill is intact.
  EXPECT_TRUE(buffer_invariants_hold(out, OutSize));
  EXPECT_EQ(out[OutSize], fill);
  EXPECT_EQ(out[OutSize + 1], fill);

  END_TEST;
}

// Test the smallest size and a typical size.
[[maybe_unused]] constexpr size_t kSmallestNameSize = 2;
[[maybe_unused]] constexpr size_t kTypicalNameSize = 32;

}  // namespace

#define NAME_UNITTEST(fname) UNITTEST(#fname, fname)

UNITTEST_START_TESTCASE(name_tests)

NAME_UNITTEST(empty_ctor<kSmallestNameSize>)
NAME_UNITTEST(empty_ctor<kTypicalNameSize>)

NAME_UNITTEST(named_ctor_empty<kSmallestNameSize>)
NAME_UNITTEST(named_ctor_empty<kTypicalNameSize>)

NAME_UNITTEST(named_ctor_small<kSmallestNameSize>)
NAME_UNITTEST(named_ctor_small<kTypicalNameSize>)

NAME_UNITTEST(named_ctor_exact<kSmallestNameSize>)
NAME_UNITTEST(named_ctor_exact<kTypicalNameSize>)

NAME_UNITTEST(named_ctor_overflow<kSmallestNameSize>)
NAME_UNITTEST(named_ctor_overflow<kTypicalNameSize>)

NAME_UNITTEST(zero_sized_output_buffer<kSmallestNameSize>)
NAME_UNITTEST(zero_sized_output_buffer<kTypicalNameSize>)

// Output buffer only contains NUL.
NAME_UNITTEST((output_buffer_size<kTypicalNameSize, 1>))

// Smallest useful output buffer.
NAME_UNITTEST((output_buffer_size<kTypicalNameSize, 2>))

// Edge cases around exactly matching the Name length.
NAME_UNITTEST((output_buffer_size<kTypicalNameSize, kTypicalNameSize - 2>))
NAME_UNITTEST((output_buffer_size<kTypicalNameSize, kTypicalNameSize - 1>))
NAME_UNITTEST((output_buffer_size<kTypicalNameSize, kTypicalNameSize>))
// Don't bother testing a larger output buffer, since most of the
// earlier tests use larger output buffers.

UNITTEST_END_TESTCASE(name_tests, "nametests", "Name test")
