// Copyright 2014 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 "feedback/feedback_daemon.h"

#include <memory>

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/ring_buffer.h"
#include "base/guid.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include <brillo/process/process.h>
#include "brillo/syslog_logging.h"
#include "components/feedback/feedback_common.h"
#include "feedback/feedback_service_interface.h"

#include <sysexits.h>

namespace {

static const char kSwitchProductId[] = "product_id";  // int
static const char kSwitchDescription[] = "desc";      // string
static const char kSwitchBucket[] = "bucket";         // string
static const char kSwitchUserEmail[] = "user_email";  // string
static const char kSwitchPageUrl[] = "page_url";      // string
static const char kSwitchRawFiles[] = "raw_files";    // colon-separated strings

const char kListSeparator[] = ":";

// Buffer size for feedback attachment files in bytes. Given that maximum
// feedback report size is ~7M and that majority of log files are under 1M, we
// set a per-file limit of 1MiB.
const int64_t kMaxFileSize = 1024 * 1024;
const int64_t kChunkSize = 64 * 1024;

bool ReadFileFromBack(const base::FilePath path, std::string* contents) {
  if (!contents) {
    LOG(ERROR) << "contents buffer is null.";
    return false;
  }

  if (path.ReferencesParent()) {
    LOG(ERROR) << "ReadFileFromBack can't be called on file paths with parent "
                  "references.";
    return false;
  }

  base::ScopedFILE fp(base::OpenFile(path, "r"));
  if (!fp) {
    PLOG(ERROR) << "Failed to open file " << path.value();
    return false;
  }

  std::unique_ptr<char[]> chunk(new char[kChunkSize]);
  base::RingBuffer<std::string, kMaxFileSize / kChunkSize> buf;
  size_t bytes_read = 0;

  // Since most logs are not seekable, read until the end with a circular
  // buffer. Note that logs will not always be kMaxFileSize even if the file
  // exceeds kMaxFileSize, depending on kChunkSize and the size of the file. It
  // could vary anywhere from (kMaxFileSize - kChunkSize + 1) to kMaxFileSize.
  while ((bytes_read = fread(chunk.get(), 1, kChunkSize, fp.get())) != 0) {
    if (bytes_read < kChunkSize) {
      chunk[bytes_read] = '\0';
    }
    buf.SaveToBuffer(std::string(chunk.get()));
  }

  contents->clear();
  for (auto it = buf.Begin(); it == buf.End(); ++it)
    contents->append(**it);

  return true;
}

void CommandlineReportStatus(base::WaitableEvent* event,
                             bool* status,
                             bool result) {
  *status = result;
  event->Signal();
}

bool FillReportFromCommandline(FeedbackCommon* report) {
  base::CommandLine* args = base::CommandLine::ForCurrentProcess();
  if (!args->HasSwitch(kSwitchProductId)) {
    LOG(ERROR) << "No product id provided";
    return false;
  }
  std::string product_id_string = args->GetSwitchValueASCII(kSwitchProductId);
  int product_id;
  if (!base::StringToInt(product_id_string, &product_id) || product_id <= 0) {
    LOG(ERROR) << "Invalid product id provided, must be a positive number";
    return false;
  }
  if (!args->HasSwitch(kSwitchDescription)) {
    LOG(ERROR) << "No description provided";
    return false;
  }

  report->AddLog("unique_guid", base::GenerateGUID());
  report->set_product_id(product_id);
  report->set_description(args->GetSwitchValueASCII(kSwitchDescription));
  report->set_user_email(args->GetSwitchValueASCII(kSwitchUserEmail));
  report->set_page_url(args->GetSwitchValueASCII(kSwitchPageUrl));
  report->set_category_tag(args->GetSwitchValueASCII(kSwitchBucket));

  std::vector<std::string> raw_files = base::SplitString(
      args->GetSwitchValueNative(kSwitchRawFiles), kListSeparator,
      base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  for (const std::string& path : raw_files) {
    auto content = std::make_unique<std::string>();

    if (!base::ReadFileToStringWithMaxSize(base::FilePath(path), content.get(),
                                           kMaxFileSize)) {
      if (content->empty()) {
        LOG(ERROR) << "Could not read raw file: " << path;
        return false;
      }
      // Skip files that are too large as it doesn't make sense to send partial
      // raw/binary files.
      LOG(WARNING) << "Skipping raw file. Exceeds max file size: " << path;
      continue;
    }

    report->AddFile(path, std::move(content));
  }

  std::vector<std::string> log_files = args->GetArgs();
  for (const std::string& path : log_files) {
    std::string content;
    if (ReadFileFromBack(base::FilePath(path), &content)) {
      report->AddLog(path, content);
    } else {
      LOG(ERROR) << "Could not read log file: " << path;
      return false;
    }
  }
  return true;
}

bool SendReport(FeedbackServiceInterface* interface, FeedbackCommon* report) {
  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
  bool status;

  report->CompressLogs();
  interface->SendFeedback(
      *report, base::Bind(&CommandlineReportStatus, &event, &status));
  event.Wait();
  return status;
}

}  // namespace

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);

  // Some libchrome calls need this.
  base::AtExitManager at_exit_manager;

  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);
  scoped_refptr<FeedbackServiceInterface> itf =
      new DBusFeedbackServiceInterface();
  scoped_refptr<FeedbackCommon> report = new FeedbackCommon();

  if (!FillReportFromCommandline(report.get())) {
    LOG(ERROR) << "Not sending report";
    return EX_USAGE;
  }

  return SendReport(itf.get(), report.get()) ? EX_OK : EX_UNAVAILABLE;
}
