// Copyright 2019 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/debuglog.h>
#include <lib/unittest/unittest.h>

#include <ktl/unique_ptr.h>

#include "debuglog_internal.h"

namespace {

bool log_format() {
  BEGIN_TEST;

  fbl::AllocChecker ac;
  ktl::unique_ptr<DLog> log = ktl::make_unique<DLog>(&ac);
  ASSERT_TRUE(ac.check(), "");

  char msg[] = "Hello World";

  log->write(DEBUGLOG_WARNING, 0, {msg, sizeof(msg)});

  dlog_header* header = reinterpret_cast<dlog_header*>(log->data);

  EXPECT_EQ(DEBUGLOG_WARNING, header->severity);
  EXPECT_EQ(0, header->flags);
  EXPECT_EQ(0u, header->pid);
  EXPECT_EQ(0u, header->tid);
  ASSERT_EQ(12, header->datalen);

  uint8_t* msg_bytes = log->data + sizeof(dlog_header);

  EXPECT_BYTES_EQ(reinterpret_cast<uint8_t*>(&msg[0]), msg_bytes, sizeof(msg));

  END_TEST;
}

bool log_wrap() {
  BEGIN_TEST;

  fbl::AllocChecker ac;
  ktl::unique_ptr<DLog> log = ktl::make_unique<DLog>(&ac);
  ASSERT_TRUE(ac.check(), "");

  char msg[] = "Hello World";
  const size_t kTruncateTarget = 5;  // An unaligned length somewhere in the middle of msg.
  const size_t pad = ALIGN4_TRUNC(DLOG_SIZE - sizeof(dlog_header) - kTruncateTarget);

  // We need to trigger some writes, but we don't care what we write, so we just need a buffer large
  // enough to be copied from. Doesn't much matter what's in it.
  char dummy[DLOG_MAX_DATA]{0};

  for (size_t to_write = pad; to_write;) {
    size_t write = to_write - sizeof(dlog_header);
    write = write > DLOG_MAX_DATA ? DLOG_MAX_DATA : write;

    log->write(DEBUGLOG_WARNING, 0, {dummy, write});
    to_write -= write + sizeof(dlog_header);
  }

  EXPECT_EQ(pad, log->head);

  log->write(DEBUGLOG_WARNING, 0, {msg, sizeof(msg)});

  dlog_header* header = reinterpret_cast<dlog_header*>(log->data + pad);

  EXPECT_EQ(DEBUGLOG_WARNING, header->severity);
  EXPECT_EQ(0, header->flags);
  EXPECT_EQ(0u, header->pid);
  EXPECT_EQ(0u, header->tid);
  ASSERT_EQ(sizeof(msg), header->datalen);

  uint8_t* msg_bytes = log->data + pad + sizeof(dlog_header);

  const size_t kTruncatedSize = DLOG_SIZE - pad - sizeof(dlog_header);

  EXPECT_BYTES_EQ(reinterpret_cast<uint8_t*>(&msg[0]), msg_bytes, kTruncatedSize);
  EXPECT_BYTES_EQ(reinterpret_cast<uint8_t*>(&msg[8]), log->data, sizeof(msg) - kTruncatedSize);

  END_TEST;
}

bool log_reader_rollout() {
  BEGIN_TEST;

  fbl::AllocChecker ac;
  ktl::unique_ptr<DLog> log = ktl::make_unique<DLog>(&ac);
  ASSERT_TRUE(ac.check(), "");

  DlogReader reader;
  reader.InitializeForTest(log.get());

  char msg[] = "Hello World";

  log->write(DEBUGLOG_WARNING, 0, {msg, sizeof(msg)});

  uint8_t read_buf[DLOG_MAX_RECORD];
  size_t got;

  ASSERT_EQ(ZX_OK, reader.Read(0, read_buf, sizeof(read_buf), &got));
  ASSERT_EQ(sizeof(dlog_header) + sizeof(msg), got);

  dlog_header* header = reinterpret_cast<dlog_header*>(read_buf);

  EXPECT_EQ(DEBUGLOG_WARNING, header->severity);

  // Header should be zeroed out.
  EXPECT_EQ(0u, header->header);

  EXPECT_EQ(0, header->flags);
  EXPECT_EQ(0u, header->pid);
  EXPECT_EQ(0u, header->tid);
  ASSERT_EQ(sizeof(msg), header->datalen);

  uint8_t* msg_bytes = &read_buf[sizeof(dlog_header)];

  EXPECT_BYTES_EQ(reinterpret_cast<uint8_t*>(&msg[0]), msg_bytes, sizeof(msg));

  for (size_t i = 0; i < DLOG_SIZE; i += sizeof(dlog_header) + sizeof(msg)) {
    log->write(DEBUGLOG_WARNING, 0, {msg, sizeof(msg)});
  }

  ASSERT_EQ(ZX_OK, reader.Read(0, read_buf, sizeof(read_buf), &got));
  ASSERT_EQ(sizeof(dlog_header) + sizeof(msg), got);

  header = reinterpret_cast<dlog_header*>(read_buf);

  EXPECT_EQ(DEBUGLOG_WARNING, header->severity);

  // The amount of data rolled out should be snuck in here.
  EXPECT_EQ(sizeof(dlog_header) + sizeof(msg), header->header);

  EXPECT_EQ(0, header->flags);
  EXPECT_EQ(0u, header->pid);
  EXPECT_EQ(0u, header->tid);
  ASSERT_EQ(sizeof(msg), header->datalen);

  msg_bytes = &read_buf[sizeof(dlog_header)];

  EXPECT_BYTES_EQ(reinterpret_cast<uint8_t*>(&msg[0]), msg_bytes, sizeof(msg));

  reader.Disconnect();
  END_TEST;
}

// Test that write fails with an error once the |DLog| has been shutdown.
bool shutdown() {
  BEGIN_TEST;

  fbl::AllocChecker ac;
  ktl::unique_ptr<DLog> log = ktl::make_unique<DLog>(&ac);
  ASSERT_TRUE(ac.check());

  // Write one message and see that it succeeds.
  char msg[] = "Message!";
  ASSERT_EQ(ZX_OK, log->write(DEBUGLOG_WARNING, 0, {msg, sizeof(msg)}));

  // Now ask the DLog to shutdown, write another, see that it fails.
  log->shutdown();
  ASSERT_EQ(ZX_ERR_BAD_STATE, log->write(DEBUGLOG_WARNING, 0, msg));

  // See that there is only one message in the DLog.
  DlogReader reader;
  reader.InitializeForTest(log.get());
  size_t got;
  uint8_t read_buf[DLOG_MAX_RECORD];
  ASSERT_EQ(ZX_OK, reader.Read(0, read_buf, sizeof(read_buf), &got));
  ASSERT_EQ(sizeof(dlog_header) + sizeof(msg), got);
  ASSERT_EQ(ZX_ERR_SHOULD_WAIT, reader.Read(0, read_buf, sizeof(read_buf), &got));
  reader.Disconnect();

  END_TEST;
}

}  // namespace

#define DEBUGLOG_UNITTEST(fname) UNITTEST(#fname, fname)

UNITTEST_START_TESTCASE(debuglog_tests)
DEBUGLOG_UNITTEST(log_format)
DEBUGLOG_UNITTEST(log_wrap)
DEBUGLOG_UNITTEST(log_reader_rollout)
DEBUGLOG_UNITTEST(shutdown)
UNITTEST_END_TESTCASE(debuglog_tests, "debuglog_tests", "Debuglog test")
