#include <sys/resource.h>
#include <sys/time.h>

#include "aos/configuration.h"
#include "aos/events/logging/log_writer.h"
#include "aos/events/shm_event_loop.h"
#include "aos/init.h"
#include "aos/logging/log_namer.h"
#include "frc971/input/joystick_state_generated.h"
#include "gflags/gflags.h"
#include "glog/logging.h"

DEFINE_string(config, "aos_config.json", "Config file to use.");

DEFINE_double(rotate_every, 0.0,
              "If set, rotate the logger after this many seconds");
DECLARE_int32(flush_size);
DEFINE_double(disabled_time, 5.0,
              "Continue logging if disabled for this amount of time or less");

std::unique_ptr<aos::logger::MultiNodeLogNamer> MakeLogNamer(
    aos::EventLoop *event_loop) {
  return std::make_unique<aos::logger::MultiNodeLogNamer>(
      absl::StrCat(aos::logging::GetLogName("fbs_log"), "/"), event_loop);
}

int main(int argc, char *argv[]) {
  gflags::SetUsageMessage(
      "This program provides a simple logger binary that logs all SHMEM data "
      "directly to a file specified at the command line when the robot is "
      "enabled and for a bit of time after.");
  aos::InitGoogle(&argc, &argv);

  aos::FlatbufferDetachedBuffer<aos::Configuration> config =
      aos::configuration::ReadConfig(FLAGS_config);

  aos::ShmEventLoop event_loop(&config.message());

  bool logging = false;
  bool enabled = false;
  aos::monotonic_clock::time_point last_disable_time =
      event_loop.monotonic_now();
  aos::monotonic_clock::time_point last_rotation_time =
      event_loop.monotonic_now();
  aos::logger::Logger logger(&event_loop);

  if (FLAGS_rotate_every != 0.0) {
    logger.set_on_logged_period([&] {
      const auto now = event_loop.monotonic_now();
      if (logging && now > last_rotation_time + std::chrono::duration<double>(
                                                    FLAGS_rotate_every)) {
        logger.Rotate();
        last_rotation_time = now;
      }
    });
  }

  event_loop.OnRun([]() {
    errno = 0;
    setpriority(PRIO_PROCESS, 0, -20);
    PCHECK(errno == 0) << ": Renicing to -20 failed.";
  });

  event_loop.MakeWatcher(
      "/roborio/aos", [&](const aos::JoystickState &joystick_state) {
        const auto timestamp = event_loop.context().monotonic_event_time;
        // Store the last time we got disabled
        if (enabled && !joystick_state.enabled()) {
          last_disable_time = timestamp;
        }
        enabled = joystick_state.enabled();

        if (!logging && enabled) {
          // Start logging if we just got enabled
          LOG(INFO) << "Starting logging";
          logger.StartLogging(MakeLogNamer(&event_loop));
          logging = true;
          last_rotation_time = event_loop.monotonic_now();
        } else if (logging && !enabled &&
                   (timestamp - last_disable_time) >
                       std::chrono::duration<double>(FLAGS_disabled_time)) {
          // Stop logging if we've been disabled for a non-negligible amount of
          // time
          LOG(INFO) << "Stopping logging";
          logger.StopLogging(event_loop.monotonic_now());
          logging = false;
        }
      });

  event_loop.Run();

  LOG(INFO) << "Shutting down";

  return 0;
}
