// 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 "src/bringup/bin/netsvc/debuglog.h"

#include <lib/component/incoming/cpp/protocol.h>
#include <lib/fit/defer.h>
#include <lib/zx/clock.h>
#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>

#include <iomanip>
#include <sstream>

#include "src/bringup/bin/netsvc/inet6.h"

constexpr zx::duration kSendDelayShort = zx::msec(100);
constexpr zx::duration kSendDelayLong = zx::sec(4);

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

LogListener::LogListener(async_dispatcher_t* dispatcher, SendFn send, bool retransmit,
                         size_t max_msg_size)
    : dispatcher_(dispatcher),
      retransmit_(retransmit),
      max_msg_size_(max_msg_size),
      send_delay_(kSendDelayShort),
      send_fn_(std::move(send)),
      timeout_task_([this](async_dispatcher_t* dispatcher, async::Task* task, zx_status_t status) {
        if (status == ZX_ERR_CANCELED) {
          return;
        }
        ZX_ASSERT_MSG(status == ZX_OK, "unexpected task status %s", zx_status_get_string(status));
        if (pkt_.has_value()) {
          // No reply. If no one is listening, reduce send rate.
          if (++num_unacked_ >= kUnackedThreshold) {
            send_delay_ = kSendDelayLong;
          }
        }
        MaybeSendLog();
      }) {
  ZX_ASSERT_MSG(max_msg_size <= NETBOOT_DEBUGLOG_MAX_DATA,
                "maximum message size %ld greater than max log data %d", max_msg_size,
                NETBOOT_DEBUGLOG_MAX_DATA);
}

void LogListener::Bind(fidl::ServerEnd<_EnclosingProtocol> server_end) {
  binding_.emplace(fidl::BindServer(
      dispatcher_, std::move(server_end), this,
      [](LogListener*, fidl::UnbindInfo info, fidl::ServerEnd<_EnclosingProtocol>) {
        if (info.status() != ZX_OK) {
          printf("netsvc: lost connection to system logs: %s\n", info.FormatDescription().c_str());
        }
      }));
}

LogListener::StagedPacket::StagedPacket(uint32_t seqno, const char* nodename,
                                        LogListener::PendingMessage&& msg)
    : contents({.magic = NETBOOT_DEBUGLOG_MAGIC, .seqno = seqno}),
      len(sizeof(contents) - (sizeof(contents.data) - msg.log_message.size())),
      message(std::move(msg)) {
  ZX_ASSERT_MSG(message.log_message.size() <= sizeof(contents.data), "invalid message size %lu",
                message.log_message.size());
  strncpy(contents.nodename, nodename, sizeof(contents.nodename) - 1);
  memcpy(contents.data, message.log_message.c_str(), message.log_message.size());
}

void LogListener::Log(LogRequestView request, LogCompleter::Sync& completer) {
  PushLogMessage(request->log);
  // Store completer.
  pending_.back().completer = completer.ToAsync();
  TryLoadNextPacket();
}

void LogListener::LogMany(LogManyRequestView request, LogManyCompleter::Sync& completer) {
  for (const fuchsia_logger::wire::LogMessage& message : request->log) {
    PushLogMessage(message);
  }
  // Store completer on last queued message.
  pending_.back().completer = completer.ToAsync();
  TryLoadNextPacket();
}

void LogListener::Done(DoneCompleter::Sync&) { ZX_PANIC("unexpected call to Done"); }

// Helpers to visit on pending message variants.
template <class... Ts>
struct overloaded : Ts... {
  using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

void LogListener::Ack(uint32_t seqno) {
  if (seqno != seqno_ || !pkt_.has_value()) {
    return;
  }
  // Received an ack. We have an active listener. Don't delay.
  num_unacked_ = 0;
  send_delay_ = kSendDelayShort;
  seqno_++;

  pkt_.value().message.Complete();
  pkt_.reset();
  TryLoadNextPacket();
}

void LogListener::PendingMessage::Complete() {
  std::visit(overloaded{[](std::monostate&) {},
                        [](LogCompleter::Async& c) {
                          c.Reply();
                          fidl::Status result = c.result_of_reply();
                          if (!result.ok()) {
                            printf("netsvc: failed to confirm logs: %s\n",
                                   result.FormatDescription().c_str());
                          }
                        },
                        [](LogManyCompleter::Async& c) {
                          c.Reply();
                          fidl::Status result = c.result_of_reply();
                          if (!result.ok()) {
                            printf("netsvc: failed to confirm logs: %s\n",
                                   result.FormatDescription().c_str());
                          }
                        }},
             completer);
}

void LogListener::PushLogMessage(const fuchsia_logger::wire::LogMessage& message) {
  std::stringstream ss;
  zx::duration timestamp(message.time);
  // Add time in format [secs.millis].
  ss << '[' << std::setw(5) << std::setfill('0') << (timestamp.to_secs());
  ss << '.' << std::setw(3) << std::setfill('0') << (timestamp.to_msecs() % 1000ULL) << ']';
  // Add PID and TID as "tid.pid".
  ss << ' ' << std::setw(5) << std::setfill('0') << message.pid;
  ss << '.' << std::setw(5) << std::setfill('0') << message.tid;

  // Add message tags.
  ss << " [";
  for (auto tag = message.tags.begin(); tag != message.tags.end(); tag++) {
    if (tag != message.tags.begin()) {
      ss << ',';
    }
    ss << tag->get();
  }
  ss << "] ";
  size_t size = ss.tellp();
  ZX_ASSERT_MSG(size < max_msg_size_, "message preamble too long: %ld", size);
  std::string_view contents = message.msg.get();
  size = std::min(max_msg_size_ - size, contents.size());
  ss << contents.substr(0, size);
  if (static_cast<size_t>(ss.tellp()) < max_msg_size_) {
    ss << '\n';
    pending_.push(PendingMessage{.log_message = ss.str()});
    return;
  }
  pending_.push(PendingMessage{.log_message = ss.str()});

  contents = contents.substr(size);
  while (!contents.empty()) {
    size_t partial = std::min(max_msg_size_, contents.size());
    pending_.push(PendingMessage{.log_message = std::string(contents.substr(0, partial))});
    contents = contents.substr(partial);
  }
  PendingMessage& last = pending_.back();
  if (last.log_message.size() < max_msg_size_) {
    last.log_message += '\n';
  } else {
    pending_.push(PendingMessage{.log_message = "\n"});
  }
}

void LogListener::TryLoadNextPacket() {
  if (pkt_.has_value() || pending_.empty()) {
    return;
  }
  pkt_.emplace(seqno_, nodename(), std::move(pending_.front()));
  pending_.pop();
  MaybeSendLog();
}

void LogListener::MaybeSendLog() {
  if (!pkt_.has_value()) {
    return;
  }
  StagedPacket& staged = pkt_.value();
  send_fn_(staged.contents, staged.len);
  if (retransmit_) {
    zx_status_t status = timeout_task_.Cancel();
    ZX_ASSERT_MSG(status == ZX_OK || status == ZX_ERR_NOT_FOUND, "failed to cancel task %s",
                  zx_status_get_string(status));
    status = timeout_task_.PostDelayed(dispatcher_, send_delay_);
    ZX_ASSERT_MSG(status == ZX_OK, "failed to schedule timeout task %s",
                  zx_status_get_string(status));
  }
}

namespace {
std::optional<LogListener> gListener;
}

zx_status_t debuglog_init(async_dispatcher_t* dispatcher) {
  zx::result log_client_end = component::Connect<fuchsia_logger::Log>();
  if (log_client_end.is_error()) {
    return log_client_end.status_value();
  }
  fidl::WireSyncClient client{std::move(log_client_end.value())};

  auto [client_end, server_end] = fidl::Endpoints<fuchsia_logger::LogListenerSafe>::Create();
  {
    fidl::Status result = client->ListenSafe(
        std::move(client_end), fidl::ObjectView<fuchsia_logger::wire::LogFilterOptions>(nullptr));
    if (!result.ok()) {
      return result.status();
    }
  }

  auto& listener = gListener.emplace(
      dispatcher,
      [](const netboot_debuglog_packet_t& pkt, size_t len) {
        zx_status_t status = udp6_send(&pkt, len, &ip6_ll_all_nodes, NETBOOT_DEBUGLOG_PORT_SERVER,
                                       NETBOOT_DEBUGLOG_PORT_ACK, false);
        if (status != ZX_OK) {
          printf("netsvc: failed to send debuglog: %s\n", zx_status_get_string(status));
        }
      },
      /* retransmit */ true, NETBOOT_DEBUGLOG_MAX_DATA);
  listener.Bind(std::move(server_end));

  return ZX_OK;
}

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

  ZX_ASSERT_MSG(gListener.has_value(), "debuglog was not initialized");
  gListener.value().Ack(pkt.seqno);
}
