// 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/message_loop/message_loop.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;
}
