// Copyright 2015 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 <string>

#include <fcntl.h>
#include <poll.h>
#include <sysexits.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <base/at_exit.h>
#include <base/command_line.h>
#include <brillo/daemons/daemon.h>
#include <base/files/file_util.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <brillo/flag_helper.h>

namespace {

const char kDefaultDeviceLogFile[] = "/sys/kernel/debug/cros_ec/console_log";

const char kDefaultLogDirectory[] = "/var/log/";

const char kCurrentLogExt[] = ".log";
const char kPreviousLogExt[] = ".previous";

const int kMaxCurrentLogSize = 10 * 1024 * 1024;

class TimberSlide : public brillo::Daemon,
                    public base::MessageLoopForIO::Watcher {
 public:
  TimberSlide(const std::string& ec_type,
              base::File device_file,
              const base::FilePath& log_dir)
      : device_file_(std::move(device_file)),
        fd_watcher_(FROM_HERE),
        total_size_(0) {
    current_log_ = log_dir.Append(ec_type + kCurrentLogExt);
    previous_log_ = log_dir.Append(ec_type + kPreviousLogExt);
  }

 private:
  int OnInit() override {
    LOG(INFO) << "Starting timberslide daemon";
    int ret = brillo::Daemon::OnInit();
    if (ret != EX_OK)
      return ret;

    RotateLogs(previous_log_, current_log_);

    CHECK(base::MessageLoopForIO::current()->WatchFileDescriptor(
              device_file_.GetPlatformFile(), true,
              base::MessageLoopForIO::WATCH_READ, &fd_watcher_, this));
    return EX_OK;
  }

  void OnFileCanWriteWithoutBlocking(int fd) override {
    LOG(FATAL) << "Unexpected call to write event handler";
  }

  void OnFileCanReadWithoutBlocking(int fd) override {
    char buffer[4096];
    int ret;

    CHECK_EQ(fd, device_file_.GetPlatformFile());

    ret = TEMP_FAILURE_RETRY(
        device_file_.ReadAtCurrentPosNoBestEffort(buffer, sizeof(buffer)));
    if (ret == 0)
      return;

    if (ret < 0) {
      PLOG(FATAL) << "Read error";
      return;
    }

    if (!base::AppendToFile(current_log_, buffer, ret)) {
      PLOG(FATAL) << "Could not append log file";
      return;
    }

    total_size_ += ret;
    if (total_size_ >= kMaxCurrentLogSize) {
      RotateLogs(previous_log_, current_log_);
      total_size_ = 0;
    }
  }

  void RotateLogs(const base::FilePath& previous_log,
                  const base::FilePath& current_log) {
    CHECK(base::DeleteFile(previous_log, /* recursive = */ false));

    if (base::PathExists(current_log))
      CHECK(base::Move(current_log, previous_log));

    base::WriteFile(current_log, "", 0);
  }

  base::File device_file_;
  base::FilePath current_log_;
  base::FilePath previous_log_;
  base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_;
  int total_size_;
};

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_string(device_log, kDefaultDeviceLogFile,
                "File where the recent EC logs are posted to.");
  DEFINE_string(log_directory, kDefaultLogDirectory,
                "Directory where the output logs should be.");
  brillo::FlagHelper::Init(argc, argv,
      "timberslide concatenates EC logs for use in debugging.");

  base::FilePath path(FLAGS_device_log);
  base::File device_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!device_file.IsValid()) {
    LOG(ERROR) << "Error opening " << FLAGS_device_log << ": "
               << base::File::ErrorToString(device_file.error_details());
    return EX_UNAVAILABLE;
  }

  std::string ec_type = path.DirName().BaseName().value();
  TimberSlide ts(ec_type, std::move(device_file),
                 (base::FilePath(FLAGS_log_directory)));

  return ts.Run();
}
