// 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 <inttypes.h>
#include <lib/zx/debuglog.h>
#include <string.h>
#include <stdio.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() {
  if (zx::debuglog::create(zx::resource(), ZX_LOG_FLAG_READABLE, &debuglog) < 0) {
    return -1;
  }

  // Set up our timeout to expire immediately, so that we check for pending log messages
  g_debuglog_next_timeout = zx_clock_get_monotonic();

  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;
  }
  logpacket_t* pkt = reinterpret_cast<logpacket_t*>(data);
  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++;
  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();
}
