// Copyright 2016 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/boot-options/boot-options.h>
#include <lib/crashlog.h>
#include <lib/debuglog.h>
#include <lib/fit/defer.h>
#include <lib/io.h>
#include <lib/lazy_init/lazy_init.h>
#include <lib/persistent-debuglog.h>
#include <lib/version.h>
#include <platform.h>
#include <stdint.h>
#include <string-file.h>
#include <string.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <dev/udisplay.h>
#include <kernel/auto_lock.h>
#include <kernel/lockdep.h>
#include <kernel/mutex.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <ktl/atomic.h>
#include <ktl/limits.h>
#include <lk/init.h>
#include <vm/vm.h>

#include "debuglog_internal.h"

#include <ktl/enforce.h>

static_assert((DLOG_SIZE & DLOG_MASK) == 0u, "must be power of two");
static_assert(DLOG_MAX_RECORD <= DLOG_SIZE, "wat");
static_assert((DLOG_MAX_RECORD & 3) == 0, "E_DONT_DO_THAT");

static lazy_init::LazyInit<DLog, lazy_init::CheckType::None, lazy_init::Destructor::Disabled> DLOG;

FILE gDlogSerialFile{[](void*, ktl::string_view str) {
                       dlog_serial_write(str);
                       return static_cast<int>(str.size());
                     },
                     nullptr};

// dlog_bypass_ will cause printfs to directly write to console. It also has the
// side effect of disabling uart Tx interrupts, which causes all of the serial
// writes to be polling.
//
// We need to preserve the compile time switch (ENABLE_KERNEL_LL_DEBUG), even
// though we add a kernel cmdline (kernel.bypass-debuglog), to bypass the debuglog.
// This is to allow very early prints in the kernel to go to the serial console.
bool dlog_bypass_ =
#if ENABLE_KERNEL_LL_DEBUG
    true;
#else
    false;
#endif

// The debuglog maintains a circular buffer of debuglog records,
// consisting of a common header (dlog_header_t) followed by up
// to 224 bytes of textual log message.  Records are aligned on
// uint32_t boundaries, so the header word which indicates the
// true size of the record and the space it takes in the fifo
// can always be read with a single uint32_t* read (the header
// or body may wrap but the initial header word never does).
//
// The ring buffer position is maintained by continuously incrementing
// head and tail pointers (type size_t, so uint64_t on 64bit systems),
//
// This allows readers to trivial compute if their local tail
// pointer has "fallen out" of the fifo (an entire fifo's worth
// of messages were written since they last tried to read) and then
// they can snap their tail to the global tail and restart
//
//
// Tail indicates the oldest message in the debuglog to read
// from, Head indicates the next space in the debuglog to write
// a new message to.  They are clipped to the actual buffer by
// DLOG_MASK.
//
//       T                     T
//  [....XXXX....]  [XX........XX]
//           H         H

void DLog::StartThreads() {
  DEBUG_ASSERT(notifier_state_.thread == nullptr);
  DEBUG_ASSERT(dumper_state_.thread == nullptr);

  auto notifier_thunk = [](void* arg) -> int { return static_cast<DLog*>(arg)->NotifierThread(); };
  if ((notifier_state_.thread = Thread::Create(kDlogNotifierThreadName, notifier_thunk, this,
                                               HIGH_PRIORITY - 1)) != NULL) {
    notifier_state_.thread->Resume();
  }

  if (platform_serial_enabled() || platform_early_console_enabled()) {
    auto dumper_thunk = [](void* arg) -> int { return static_cast<DLog*>(arg)->DumperThread(); };
    if ((dumper_state_.thread = Thread::Create(kDlogDumperThreadName, dumper_thunk, this,
                                               HIGH_PRIORITY - 2)) != NULL) {
      dumper_state_.thread->Resume();
    }
  }
}

zx_status_t DLog::Shutdown(zx_time_t deadline) {
  dprintf(INFO, "Shutting down debuglog\n");

  // It is critical to set the shutdown flag first, to prevent new records from
  // being inserted because the dumper thread will continue to read records
  // and drain the queue even after shutdown is requested.  If we don't stop the
  // flow up stream, then a sufficiently speedy write could prevent the
  // dumper thread from terminating.
  {
    Guard<MonitoredSpinLock, IrqSave> guard{&lock_, SOURCE_TAG};
    this->shutdown_requested_ = true;
  }

  auto ShutdownThread = [deadline](ThreadState& state, const char* name) -> zx_status_t {
    const bool already_shutdown = state.shutdown_requested.exchange(true);
    if (already_shutdown) {
      // If shutdown has already been requested then either a full debuglog shutdown has already
      // happened, or we are currently racing with one. In the former case we could immediately
      // return, but in the latter we need to wait until they have finished shutdown. Given how
      // unlikely this whole scenario is, and the comparative difficulty of synchronizing the second
      // scenario we just wait till the deadline. Most likely whoever was already shutting down the
      // debuglog will have performed halt/reboot before this sleep completes.
      Thread::Current::Sleep(deadline);
      return ZX_OK;
    }

    state.event.Signal();
    if (state.thread != nullptr) {
      zx_status_t status = state.thread->Join(nullptr, deadline);
      if (status != ZX_OK) {
        dprintf(INFO, "Failed to join %s thread: %d\n", name, status);
        return status;
      }
      state.thread = nullptr;
    }
    return ZX_OK;
  };

  // Shutdown the notifier thread first. Ordering is important because the
  // notifier thread is responsible for passing log records to the dumper.
  zx_status_t notifier_status = ShutdownThread(notifier_state_, kDlogNotifierThreadName);
  zx_status_t dumper_status = ShutdownThread(dumper_state_, kDlogDumperThreadName);

  // If one of them failed, return the status corresponding to the first
  // failure.
  if (notifier_status != ZX_OK) {
    return notifier_status;
  }
  return dumper_status;
}

void DLog::PanicStart() {
  // Stop processing log writes they'll fail over to kernel console and serial.
  panic_ = true;
}

void DLog::BluescreenInit() {
  udisplay_bind_gfxconsole();

  // replay debuglog?

  // Print panic string.
  //
  // WARNING: This string is detected by external tools to detect
  // kernel panics during tests. Changes should be made with care.
  printf("\nZIRCON KERNEL PANIC\n\n");

  // Print uptime, current CPU, and version information.
  printf("UPTIME: %" PRIi64 "ms, CPU: %" PRIu32 "\n", current_time() / ZX_MSEC(1),
         arch_curr_cpu_num());
  print_backtrace_version_info();
  g_crashlog.base_address = (uintptr_t)__code_start;
}

zx_status_t DLog::Write(uint32_t severity, uint32_t flags, ktl::string_view str) {
  str = str.substr(0, DLOG_MAX_DATA);

  const char* ptr = str.data();

  const size_t len = str.size();

  if (panic_) {
    return ZX_ERR_BAD_STATE;
  }

  // Our size "on the wire" must be a multiple of 4, so we know that worst case
  // there will be room for a header preamble skipping the last n bytes when the
  // fifo wraps
  size_t wiresize = sizeof(dlog_header) + ALIGN4(len);

  // Prepare the record header before taking the lock
  dlog_header_t hdr;
  hdr.preamble = static_cast<uint32_t>(DLOG_HDR_SET(wiresize, sizeof(dlog_header) + len));
  hdr.datalen = static_cast<uint16_t>(len);
  hdr.severity = static_cast<uint8_t>(severity);
  hdr.flags = static_cast<uint8_t>(flags);
  hdr.timestamp = current_time();
  Thread* t = Thread::Current::Get();
  if (t) {
    hdr.pid = t->pid();
    hdr.tid = t->tid();
  } else {
    hdr.pid = 0;
    hdr.tid = 0;
  }

  bool holding_thread_lock;
  {
    Guard<MonitoredSpinLock, IrqSave> guard{&lock_, SOURCE_TAG};

    hdr.sequence = sequence_count_;

    if (shutdown_requested_) {
      return ZX_ERR_BAD_STATE;
    }

    // Discard records at tail until there is enough
    // space for the new record.
    while ((head_ - tail_) > (DLOG_SIZE - wiresize)) {
      uint32_t preamble = *reinterpret_cast<uint32_t*>(data_ + (tail_ & DLOG_MASK));
      tail_ += DLOG_HDR_GET_FIFOLEN(preamble);
    }

    size_t offset = head_ & DLOG_MASK;
    size_t fifospace = DLOG_SIZE - offset;

    if (fifospace >= wiresize) {
      // everything fits in one write, simple case!
      memcpy(data_ + offset, &hdr, sizeof(hdr));
      memcpy(data_ + offset + sizeof(hdr), ptr, len);
    } else if (fifospace < sizeof(hdr)) {
      // the wrap happens in the header
      memcpy(data_ + offset, &hdr, fifospace);
      memcpy(data_, reinterpret_cast<uint8_t*>(&hdr) + fifospace, sizeof(hdr) - fifospace);
      memcpy(data_ + (sizeof(hdr) - fifospace), ptr, len);
    } else {
      // the wrap happens in the data
      memcpy(data_ + offset, &hdr, sizeof(hdr));
      offset += sizeof(hdr);
      fifospace -= sizeof(hdr);
      memcpy(data_ + offset, ptr, fifospace);
      memcpy(data_, ptr + fifospace, len - fifospace);
    }
    head_ += wiresize;
    sequence_count_++;

    // Need to check this before re-releasing the log lock, since we may
    // re-enable interrupts while doing that.  If interrupts are enabled when we
    // make this check, we could see the following sequence of events between
    // two CPUs and incorrectly conclude we are holding the thread lock:
    // C2: Acquire thread_lock
    // C1: Running this thread, evaluate thread_lock.HolderCpu() -> C2
    // C1: Context switch away
    // C2: Release thread_lock
    // C2: Context switch to this thread
    // C2: Running this thread, evaluate arch_curr_cpu_num() -> C2
    holding_thread_lock = thread_lock.HolderCpu() == arch_curr_cpu_num();
  }

  // If we happen to be called from within the global thread lock, use a special
  // version of event signal.
  if (holding_thread_lock) {
    thread_lock.AssertHeld();
    notifier_state_.event.SignalLocked();
  } else {
    notifier_state_.event.Signal();
  }

  return ZX_OK;
}

size_t DLog::RenderToCrashlog(ktl::span<char> target_span) const {
  // Try to obtain the spinlock which protects the debuglog.  If this fails, do
  // not proceed, simply render a message to the crashlog indicating that we are
  // unable to proceed.
  //
  // At this point in a panic, all bets are off.  If we took an exception while
  // holding this lock, attempting to re-obtain the lock at this point in time
  // could result in either deadlock, or infinite exception recursion, either of
  // which would be Very Bad.  Best to just say that we cannot actually recover
  // any portion of the debuglog to the crashlog and move on.
  InterruptDisableGuard irqd;
  Guard<MonitoredSpinLock, TryLockNoIrqSave> guard{&lock_, SOURCE_TAG};
  if (static_cast<bool>(guard)) {
    return RenderToCrashlogLocked(target_span);
  } else {
    StringFile target(target_span);
    fprintf(&target,
            "Cannot render debuglog to the crashlog! Failed to acquire the debuglog spinlock.\n");
    return target.used_region().size();
  }
}

size_t DLog::RenderToCrashlogLocked(ktl::span<char> target_span) const {
  if ((target_span.data() == nullptr) || (target_span.size() == 0)) {
    return 0;
  }

  StringFile target(target_span);

  // Check for obvious any signs that the log may have become corrupted.  Head
  // and tail are absolute offsets into the ring buffer, and old records are
  // destroyed to make room for new ones during write operations.  Because of
  // this, it should not be possible for tail to ever be greater than head, and
  // the distance between head and tail should never be larger than the size of
  // the log buffer.
  if ((tail_ > head_) || ((head_ - tail_) > DLOG_SIZE)) {
    fprintf(&target, "Debug log appears corrupt: (head, tail) = (%zu, %zu)\n", head_, tail_);
    return target.used_region().size();
  }

  // A small helper to compute the size of a record, were it to be rendered.
  auto RenderedRecordSize = [](const Record& r) -> size_t {
    return DLog::MeasureRenderedHeader(r.hdr) + r.region1.size() + r.region2.size() +
           (r.ends_with_newline ? 0 : 1);
  };

  // Figure out how much space the whole log would take.
  size_t space_consumed = 0;
  for (size_t offset = tail_; offset < head_;) {
    auto res = ReadRecord(offset, &target);
    if (!res.is_ok()) {
      return target.used_region().size();
    }

    Record& record = res.value();
    space_consumed += RenderedRecordSize(record);
    offset += DLOG_HDR_GET_FIFOLEN(record.hdr.preamble);
  }

  // Starting from the end, skip records until we get to the point where we can
  // fit the rest of the rendered data into target_span, then render the rest of
  // the records.
  for (size_t offset = tail_; offset < head_;) {
    auto res = ReadRecord(offset, &target);
    if (!res.is_ok()) {
      return target.used_region().size();
    }

    Record& record = res.value();
    if (space_consumed > target_span.size()) {
      space_consumed -= RenderedRecordSize(record);
    } else {
      target.Skip(FormatHeader(target.available_region(), record.hdr));
      target.Write(record.region1);
      target.Write(record.region2);
      if (!record.ends_with_newline) {
        target.Write("\n");
      }
    }

    offset += DLOG_HDR_GET_FIFOLEN(record.hdr.preamble);
  }

  return target.used_region().size();
}

void DLog::OutputLogMessage(ktl::string_view log) {
  console_write(log);
  dlog_serial_write(log);
}

// The debuglog notifier thread observes when the debuglog is
// written and calls the notify callback on any readers that
// have one so they can process new log messages.
int DLog::NotifierThread() {
  for (;;) {
    if (notifier_state_.shutdown_requested.load()) {
      break;
    }
    notifier_state_.event.Wait();

    // notify readers that new DLOG items were posted
    {
      Guard<Mutex> guard(&readers_lock_);
      for (DlogReader& reader : readers) {
        reader.Notify();
      }
    }
  }
  return ZX_OK;
}

int DLog::DumperThread() {
  // assembly buffer with room for log text plus header text
  char tmp[DLOG_MAX_DATA + 128];

  dlog_record_t rec;
  DlogReader reader;
  reader.Initialize([](void* cookie) { static_cast<Event*>(cookie)->Signal(); },
                    &dumper_state_.event, this);

  auto disconnect = fit::defer([&reader]() { reader.Disconnect(); });

  uint64_t expected_sequence = 0;

  bool done = false;
  while (!done) {
    dumper_state_.event.Wait();

    // If shutdown has been requested, this will be our last loop iteration.
    //
    // We do not break early because we guarantee that any messages logged prior to the start of the
    // shutdown sequence will be emitted.
    done = dumper_state_.shutdown_requested.load();

    // Read out all the records and dump them to the kernel console.
    size_t actual;
    while (reader.Read(0, &rec, &actual) == ZX_OK) {
      StringFile tmp_file({tmp, sizeof(tmp)});
      uint64_t gap = rec.hdr.sequence - expected_sequence;
      if (gap > 0) {
        fprintf(&tmp_file, "debuglog: dropped %zu messages\n", gap);

        const ktl::string_view sv = tmp_file.as_string_view();
        OutputLogMessage(sv);
      }
      expected_sequence = rec.hdr.sequence + 1;

      tmp_file.Skip(FormatHeader(tmp_file.available_region(), rec.hdr));
      tmp_file.Write({rec.data, rec.hdr.datalen});
      // If the record didn't end with a newline, add one now.
      if ((rec.hdr.datalen == 0) || (rec.data[rec.hdr.datalen - 1] != '\n')) {
        tmp_file.Write("\n");
      }
      const ktl::string_view sv = tmp_file.as_string_view();
      OutputLogMessage(sv);
    }
  }

  return 0;
}

// TODO: support reading multiple messages at a time
// TODO: filter with flags
zx_status_t DlogReader::Read(uint32_t flags, dlog_record_t* record, size_t* actual) {
  zx_status_t status = ZX_ERR_SHOULD_WAIT;

  {
    Guard<MonitoredSpinLock, IrqSave> guard{&log_->lock_, SOURCE_TAG};

    size_t rtail = tail_;

    // If the read-tail is not within the range of log_-tail..log_-head
    // this reader has been lapped by a writer and we reset our read-tail
    // to the current log_-tail.
    //
    if ((log_->head_ - log_->tail_) < (log_->head_ - rtail)) {
      rtail = log_->tail_;
    }

    if (rtail != log_->head_) {
      // Attempt to read the header into the user supplied buffer.
      status = log_->ReassembleFromOffset(
          rtail, {reinterpret_cast<uint8_t*>(&record->hdr), sizeof(record->hdr)});
      if (status != ZX_OK) {
        guard.Release();  // Drop the dlog lock before panicking, or asserting anything.
        DEBUG_ASSERT_MSG(status == ZX_OK,
                         "DLOG read failure at offset %zu. Failed to reassemble header (%d)\n",
                         rtail, status);
        return status;
      }

      // Perform consistency checks of the lengths.
      const size_t readlen = DLOG_HDR_GET_READLEN(record->hdr.preamble);
      if ((readlen < sizeof(record->hdr)) ||
          ((readlen - sizeof(record->hdr)) != record->hdr.datalen)) {
        guard.Release();  // Drop the dlog lock before panicking, or asserting anything.
        DEBUG_ASSERT_MSG(
            false,
            "DLOG read failure at offset %zu. Bad lengths (pre %zu, hdr_sz %zu, datalen %hu)\n",
            rtail, readlen, sizeof(record->hdr), record->hdr.datalen);
        return ZX_ERR_INTERNAL;
      }

      // Reassemble the data from the ring buffer.
      status = log_->ReassembleFromOffset(
          rtail + sizeof(record->hdr),
          {reinterpret_cast<uint8_t*>(record->data), record->hdr.datalen});
      if (status != ZX_OK) {
        guard.Release();  // Drop the dlog lock before panicking, or asserting anything.
        DEBUG_ASSERT_MSG(
            status == ZX_OK,
            "DLOG read failure at offset %zu. Failed to reassemble %hu data bytes (%d)\n", rtail,
            record->hdr.datalen, status);
        return ZX_ERR_INTERNAL;
      }

      // Everything went well.  Advance the tail pointer, report the actual length read, and get
      // out.
      rtail += DLOG_HDR_GET_FIFOLEN(record->hdr.preamble);
      *actual = DLOG_HDR_GET_READLEN(record->hdr.preamble);
      record->hdr.preamble = 0;
      status = ZX_OK;
    }

    tail_ = rtail;
  }

  return status;
}

DlogReader::~DlogReader() {
  // DlogReaders must be disconnected when destroyed.
  DEBUG_ASSERT(!InContainer());
}

void DlogReader::Initialize(NotifyCallback* notify, void* cookie, DLog* log) {
  // A DlogReader can only be initialized once.
  DEBUG_ASSERT(log_ == nullptr);

  if (log) {
    log_ = log;
  } else {
    log_ = &DLOG.Get();
  }

  notify_ = notify;
  cookie_ = cookie;

  Guard<Mutex> readers_guard(&log_->readers_lock_);
  log_->readers.push_back(this);

  bool do_notify = false;

  {
    Guard<MonitoredSpinLock, IrqSave> guard{&log_->lock_, SOURCE_TAG};
    tail_ = log_->tail_;
    do_notify = (log_->tail_ != log_->head_);
  }

  // simulate notify callback for events that arrived
  // before we were initialized
  if (do_notify && notify) {
    notify(cookie);
  }
}

void DlogReader::Disconnect() {
  if (log_) {
    Guard<Mutex> guard(&log_->readers_lock_);
    log_->readers.erase(*this);
  }
}

void DlogReader::Notify() {
  if (notify_) {
    notify_(cookie_);
  }
}

// Called first thing in init, so very early printfs can go to serial console.
void dlog_init_early() {
  // Construct the debuglog. Done here so we can construct it manually before
  // the global constructors are run.
  DLOG.Initialize();
  persistent_dlog_init_early();
}

// Called after kernel cmdline options are parsed (in platform_early_init()).
// The compile switch (if enabled) overrides the kernel cmdline switch.
void dlog_bypass_init() {
  if (dlog_bypass_ == false) {
    dlog_bypass_ = gBootOptions->bypass_debuglog;
  }
}

zx_status_t dlog_write(uint32_t severity, uint32_t flags, ktl::string_view str) {
  return DLOG->Write(severity, flags, str);
}

// Common bottleneck between sys_debug_write() and debuglog_dumper()
// to reduce interleaved messages between the serial console and the
// debuglog drainer.

namespace {
DECLARE_SINGLETON_MUTEX(DlogSerialWriteLock);
}  // namespace

void dlog_serial_write(ktl::string_view str) {
  if (dlog_bypass_ == true) {
    // If LL DEBUG is enabled we take this path which uses a spinlock
    // and prevents the direct writes from the kernel from interleaving
    // with our output
    serial_write(str);
  } else {
    // Otherwise we can use a mutex and avoid time under spinlock
    Guard<Mutex> guard{DlogSerialWriteLock::Get()};
    platform_dputs_thread(str.data(), str.size());
  }
}

void dlog_bluescreen_init() { DLOG->BluescreenInit(); }
void dlog_panic_start() { DLOG->PanicStart(); }
void dlog_force_panic() { dlog_bypass_ = true; }
zx_status_t dlog_shutdown(zx_time_t deadline) { return DLOG->Shutdown(deadline); }
size_t dlog_render_to_crashlog(ktl::span<char> target) { return DLOG->RenderToCrashlog(target); }

LK_INIT_HOOK(
    debuglog, [](uint level) { DLOG->StartThreads(); }, LK_INIT_LEVEL_PLATFORM)
