// Copyright 2017 The Chromium OS 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 "vm_tools/syslog/forwarder.h"

#include <stdint.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include <array>
#include <string>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <base/strings/stringprintf.h>

#include "vm_tools/syslog/scrubber.h"

using std::string;

namespace vm_tools {
namespace syslog {
Forwarder::Forwarder(base::ScopedFD destination)
    : destination_(std::move(destination)) {}

grpc::Status Forwarder::CollectKernelLogs(grpc::ServerContext* ctx,
                                          const vm_tools::LogRequest* request,
                                          vm_tools::EmptyMessage* response) {
  DCHECK(ctx);
  DCHECK(request);

  return ForwardLogs(ctx, request, true /*is_kernel*/);
}

grpc::Status Forwarder::CollectUserLogs(grpc::ServerContext* ctx,
                                        const vm_tools::LogRequest* request,
                                        vm_tools::EmptyMessage* response) {
  DCHECK(ctx);
  DCHECK(request);

  return ForwardLogs(ctx, request, false /*is_kernel*/);
}

grpc::Status Forwarder::ForwardLogs(grpc::ServerContext* ctx,
                                    const vm_tools::LogRequest* request,
                                    bool is_kernel) {
  // CID 0 is reserved so we use it to indicate an unknown peer.
  uint64_t cid = 0;
  if (sscanf(ctx->peer().c_str(), "vsock:%lu", &cid) != 1) {
    LOG(WARNING) << "Failed to parse peer address " << ctx->peer();
  }

  string prefix =
      base::StringPrintf(" VM(%lu): %s", cid, is_kernel ? "kernel: " : "");

  std::vector<string> priorities, timestamps, contents;
  priorities.reserve(request->records_size());
  timestamps.reserve(request->records_size());
  contents.reserve(request->records_size());

  constexpr uint8_t kIovCount = 4;
  std::vector<std::array<struct iovec, kIovCount>> iovs;
  iovs.reserve(request->records_size());

  std::vector<struct mmsghdr> msgs;
  msgs.reserve(request->records_size());

  for (const vm_tools::LogRecord& record : request->records()) {
    priorities.emplace_back(ParseProtoSeverity(record.severity()));
    timestamps.emplace_back(ParseProtoTimestamp(record.timestamp()));
    contents.emplace_back(ScrubProtoContent(record.content()));

    // Build the message.
    iovs.emplace_back(std::array<struct iovec, kIovCount>{{
        {
            .iov_base = static_cast<void*>(
                const_cast<char*>(priorities.back().c_str())),
            .iov_len = priorities.back().size(),
        },
        {
            .iov_base = static_cast<void*>(
                const_cast<char*>(timestamps.back().c_str())),
            .iov_len = timestamps.back().size(),
        },
        {
            .iov_base = static_cast<void*>(const_cast<char*>(prefix.c_str())),
            .iov_len = prefix.size(),
        },
        {
            .iov_base =
                static_cast<void*>(const_cast<char*>(contents.back().c_str())),
            .iov_len = contents.back().size(),
        },
    }});

    msgs.emplace_back((struct mmsghdr){
        .msg_hdr =
            {  // NOLINT(whitespace/braces)
                .msg_name = nullptr,
                .msg_namelen = 0,
                .msg_iov = iovs.back().data(),
                .msg_iovlen = iovs.back().size(),
                .msg_control = nullptr,
                .msg_controllen = 0,
                .msg_flags = 0,
            },
        .msg_len = 0,
    });
  }

  if (sendmmsg(destination_.get(), msgs.data(), msgs.size(), 0 /*flags*/) !=
      msgs.size()) {
    PLOG(ERROR) << "Failed to send log records to syslog daemon";
    return grpc::Status(grpc::INTERNAL,
                        "failed to send log records to syslog daemon");
  }

  return grpc::Status::OK;
}

}  // namespace syslog
}  // namespace vm_tools
