// Copyright 2018 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 "crash-reporter/anomaly_collector.h"

#include <pwd.h>
#include <unistd.h>

#include <string>

#include <base/at_exit.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop/message_loop.h>
#include <brillo/flag_helper.h>
#include <brillo/process.h>
#include <brillo/syslog_logging.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>

#include "metrics_event/proto_bindings/metrics_event.pb.h"

namespace {

// D-Bus handle for sending OOM-kill signals.  This is owned by |dbus| in
// main().
dbus::ExportedObject* g_dbus_exported_object = nullptr;

// Path to crash_reporter.
const char* crash_reporter_path = "/sbin/crash_reporter";

// Prepares for sending D-Bus signals.  Returns a D-Bus object, which provides
// a handle for sending signals.
scoped_refptr<dbus::Bus> SetUpDBus(void) {
  // Connect the bus.
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  scoped_refptr<dbus::Bus> dbus(new dbus::Bus(options));
  CHECK(dbus);
  CHECK(dbus->Connect()) << "Failed to connect to D-Bus";
  // Export a bus object so that other processes can register signal handlers
  // (this service only sends signals, no methods are exported).
  g_dbus_exported_object = dbus->GetExportedObject(
      dbus::ObjectPath(anomaly_collector::kAnomalyEventServicePath));
  CHECK(g_dbus_exported_object);
  return dbus;
}

}  // namespace

// Callback to run crash-reporter.
void RunCrashReporter(int filter, const char* flag, const char* input_path) {
  brillo::ProcessImpl cmd;
  cmd.RedirectInput(input_path);
  cmd.AddArg(crash_reporter_path);
  if (!filter)
    cmd.AddArg(flag);
  CHECK_EQ(0, cmd.Run());
}

void CDBusSendOomSignal(const int64_t oom_timestamp_ms) {
  dbus::Signal signal(anomaly_collector::kAnomalyEventServiceInterface,
                      anomaly_collector::kAnomalyEventSignalName);
  dbus::MessageWriter writer(&signal);
  metrics_event::Event payload;
  payload.set_type(metrics_event::Event_Type_OOM_KILL_KERNEL);
  payload.set_timestamp(oom_timestamp_ms);
  writer.AppendProtoAsArrayOfBytes(payload);
  CHECK(g_dbus_exported_object);
  g_dbus_exported_object->SendSignal(&signal);
}

int main(int argc, char* argv[]) {
  // Sim sala bim!  These are needed to send D-Bus signals.  Even though they
  // are not used directly, they set up some global state needed by the D-Bus
  // library.
  base::MessageLoop message_loop;
  base::AtExitManager at_exit_manager;

  DEFINE_bool(filter, false, "Input is stdin and output is stdout");
  DEFINE_bool(test, false, "Run self-tests");

  brillo::FlagHelper::Init(argc, argv, "Crash Helper: Anomaly Collector");
  brillo::OpenLog("anomaly_collector", true);
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  if (FLAGS_filter)
    crash_reporter_path = "/bin/cat";
  else if (FLAGS_test)
    crash_reporter_path = "./anomaly_collector_test_reporter.sh";

  scoped_refptr<dbus::Bus> dbus;
  if (!FLAGS_test)
    dbus = SetUpDBus();

  return AnomalyLexer(FLAGS_filter, FLAGS_test);
}
