// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "debuglog.h"

#include <fuchsia/boot/llcpp/fidl.h>
#include <inttypes.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/clock.h>
#include <lib/zx/debuglog.h>
#include <stdio.h>
#include <string.h>
#include <zircon/boot/netboot.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>

#include "netsvc.h"
#include "tftp.h"

#define MAX_LOG_LINE (ZX_LOG_RECORD_MAX + 32)

static zx::debuglog debuglog;
static logpacket_t pkt;
static size_t pkt_len;

static volatile uint32_t seqno = 1;
static volatile uint32_t pending = 0;

static zx_time_t g_debuglog_next_timeout = ZX_TIME_INFINITE;

zx_time_t debuglog_next_timeout() { return g_debuglog_next_timeout; }

#define SEND_DELAY_SHORT ZX_MSEC(100)
#define SEND_DELAY_LONG ZX_SEC(4)

// Number of consecutive unacknowledged packets we will send before reducing send rate.
static const unsigned kUnackedThreshold = 5;

// Number of consecutive packets that went unacknowledged. Is reset on acknowledgment.
static unsigned num_unacked = 0;

// How long to wait between sending.
static zx_duration_t send_delay = SEND_DELAY_SHORT;

static size_t get_log_line(char* out) {
  char buf[ZX_LOG_RECORD_MAX + 1];
  zx_log_record_t* rec = reinterpret_cast<zx_log_record_t*>(buf);
  for (;;) {
    if (debuglog.read(0, rec, ZX_LOG_RECORD_MAX) > 0) {
      if (rec->datalen && (rec->data[rec->datalen - 1] == '\n')) {
        rec->datalen--;
      }
      // records flagged for local display are ignored
      if (rec->flags & ZX_LOG_LOCAL) {
        continue;
      }
      rec->data[rec->datalen] = 0;
      snprintf(out, MAX_LOG_LINE, "[%05d.%03d] %05" PRIu64 ".%05" PRIu64 "> %s\n",
               static_cast<int>(rec->timestamp / 1000000000ULL),
               static_cast<int>((rec->timestamp / 1000000ULL) % 1000ULL), rec->pid, rec->tid,
               rec->data);
      return strlen(out);
    } else {
      return 0;
    }
  }
}

int debuglog_init() {
  zx::channel local, remote;
  zx_status_t status = zx::channel::create(0, &local, &remote);
  if (status != ZX_OK) {
    return status;
  }
  status = fdio_service_connect("/svc/fuchsia.boot.ReadOnlyLog", remote.release());
  if (status != ZX_OK) {
    return status;
  }
  fidl::WireSyncClient<fuchsia_boot::ReadOnlyLog> read_only_log(std::move(local));
  auto result = read_only_log.Get();
  if (result.status() != ZX_OK) {
    return result.status();
  }
  debuglog = std::move(result->log);

  // Set up our timeout to expire immediately, so that we check for pending log messages
  g_debuglog_next_timeout = zx::clock::get_monotonic().get();

  seqno = 1;
  pending = 0;

  return 0;
}

// If we have an outstanding (unacknowledged) log, resend it. Otherwise, send new logs, if we
// have any.
static void debuglog_send() {
  if (pending == 0) {
    pkt.magic = NB_DEBUGLOG_MAGIC;
    pkt.seqno = seqno;
    strncpy(pkt.nodename, nodename(), sizeof(pkt.nodename) - 1);
    pkt_len = 0;
    while (pkt_len < (MAX_LOG_DATA - MAX_LOG_LINE)) {
      size_t r = get_log_line(pkt.data + pkt_len);
      if (r > 0) {
        pkt_len += r;
      } else {
        break;
      }
    }
    if (pkt_len) {
      // include header and nodename in length
      pkt_len += MAX_NODENAME_LENGTH + sizeof(uint32_t) * 2;
      pending = 1;
    } else {
      goto done;
    }
  }
  udp6_send(&pkt, pkt_len, &ip6_ll_all_nodes, DEBUGLOG_PORT, DEBUGLOG_ACK_PORT, false);
done:
  g_debuglog_next_timeout = zx_deadline_after(send_delay);
}

void debuglog_recv(void* data, size_t len, bool is_mcast) {
  // The only message we should be receiving is acknowledgement of our last transmission
  if (!pending) {
    return;
  }
  if ((len != 8) || is_mcast) {
    return;
  }
  // Copied not cast in-place to satisfy alignment requirements flagged by ubsan (see
  // fxbug.dev/45798).
  logpacket_t pkt;
  memcpy(&pkt, data, sizeof(logpacket_t));
  if ((pkt.magic != NB_DEBUGLOG_MAGIC) || (pkt.seqno != seqno)) {
    return;
  }

  // Received an ack. We have an active listener. Don't delay.
  num_unacked = 0;
  send_delay = SEND_DELAY_SHORT;

  seqno = seqno + 1;
  pending = 0;
  debuglog_send();
}

void debuglog_timeout_expired() {
  if (pending) {
    // No reply. If noone is listening, reduce send rate.
    if (++num_unacked >= kUnackedThreshold) {
      send_delay = SEND_DELAY_LONG;
    }
  }
  debuglog_send();
}
