// Copyright 2019 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 "log_listener_log_sink.h"

#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/logger.h>
#include <lib/syslog/wire_format.h>

namespace netemul {
namespace internal {

/*
 * LogListenerLogSinkImpl
 *
 * public
 */

LogListenerLogSinkImpl::LogListenerLogSinkImpl(
    fidl::InterfaceRequest<fuchsia::logger::LogListenerSafe> request, std::string prefix,
    zx::socket log_sink, async_dispatcher_t* dispatcher)
    : LogListenerImpl(std::move(request), "@" + prefix, dispatcher) {
  if (log_sink.is_valid()) {
    log_sock_ = std::move(log_sink);
  } else {
    auto svc_dir = sys::ServiceDirectory::CreateFromNamespace();
    fuchsia::logger::LogSinkPtr log;
    svc_dir->Connect(log.NewRequest(dispatcher));
    zx::socket out;
    zx::socket::create(ZX_SOCKET_DATAGRAM, &out, &log_sock_);
    log->Connect(std::move(out));
  }
}

/*
 * LogListenerLogSinkImpl
 *
 * protected
 */

void LogListenerLogSinkImpl::LogImpl(fuchsia::logger::LogMessage m) {
  fx_log_packet_t packet;
  packet.metadata.dropped_logs = dropped_logs_;
  packet.metadata.pid = m.pid;
  packet.metadata.tid = m.tid;
  packet.metadata.severity = m.severity;
  packet.metadata.time = m.time;
  bool inline_prefix = true;
  if (m.tags.size() < FX_LOG_MAX_TAGS) {
    m.tags.push_back(prefix_);
    inline_prefix = false;
  }

  // insert tags:
  size_t pos = 0;
  for (const auto& tag : m.tags) {
    auto len = tag.length();
    if (len > FX_LOG_MAX_TAG_LEN - 1) {
      len = FX_LOG_MAX_TAG_LEN - 1;
    }
    packet.data[pos] = len;
    pos++;
    memcpy(&packet.data[pos], tag.c_str(), len);
    pos += len;
  }
  packet.data[pos++] = 0;
  if (inline_prefix && prefix_.length() + 4 + pos < sizeof(packet.data)) {
    packet.data[pos++] = '[';
    memcpy(&packet.data[pos], prefix_.c_str(), prefix_.length());
    pos += prefix_.length();
    packet.data[pos++] = ']';
    packet.data[pos++] = ' ';
  }
  ZX_ASSERT(pos <= sizeof(packet.data));
  auto remain = sizeof(packet.data) - pos;
  if (m.msg.length() + 1 < remain) {
    remain = m.msg.length() + 1;
  }
  if (remain > 0) {
    memcpy(&packet.data[pos], m.msg.c_str(), remain);
    packet.data[pos + remain - 1] = 0;
    pos += remain;
  }

  size_t actual;
  pos += sizeof(packet.metadata);
  if (log_sock_.write(0, &packet, pos, &actual) == ZX_OK && actual == pos) {
    dropped_logs_ = 0;
  } else {
    dropped_logs_++;
  }
}

}  // namespace internal
}  // namespace netemul
