// 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 <cinttypes>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#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, bool is_socket_destination)
    : destination_(std::move(destination)),
      is_socket_destination_(is_socket_destination) {}

void Forwarder::SetFileDestination(base::ScopedFD destination) {
  CHECK(destination.is_valid());
  is_socket_destination_ = false;
  destination_.swap(destination);
}

grpc::Status Forwarder::ForwardLogs(int64_t cid,
                                    const vm_tools::LogRequest& request) {
  CHECK(destination_.is_valid());
  string prefix = base::StringPrintf(" VM(%" PRId64 "): ", cid);

  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()));

    if (is_socket_destination_) {
      // 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){
          // clang-format off
          .msg_hdr = {
              .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,
          },
          // clang-format on
          .msg_len = 0,
      });
    }
  }

  if (is_socket_destination_) {
    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");
    }
  } else {
    // Write messages to file
    std::ostringstream lines_stream;
    for (int i = 0; i < request.records_size(); ++i) {
      lines_stream << timestamps[i] << " " << priorities[i] << " " << prefix
                   << contents[i] << "\n";
    }
    const std::string lines = lines_stream.str();
    if (!base::WriteFileDescriptor(destination_.get(), lines.c_str(),
                                   lines.size())) {
      PLOG(ERROR) << "Failed to write log records to file" << lines;
      return grpc::Status(grpc::INTERNAL,
                          "failed to write log records to file");
    }
  }

  return grpc::Status::OK;
}

}  // namespace syslog
}  // namespace vm_tools
