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

#include "absl/flags/flag.h"
#include "absl/flags/usage.h"
#include "absl/log/check.h"
#include "absl/log/log.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 "aos/util/filesystem_generated.h"
#include "frc971/input/joystick_state_generated.h"

ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");

ABSL_FLAG(double, rotate_every, 0.0,
          "If set, rotate the logger after this many seconds");
ABSL_DECLARE_FLAG(int32_t, flush_size);
ABSL_FLAG(double, disabled_time, 5.0,
          "Continue logging if disabled for this amount of time or less");
ABSL_FLAG(bool, direct, false,
          "If true, write using O_DIRECT and write 512 byte aligned blocks "
          "whenever possible.");

std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
    aos::EventLoop *event_loop) {
  std::optional<std::string> log_name =
      aos::logging::MaybeGetLogName("image_log");

  if (!log_name.has_value()) {
    return nullptr;
  }

  return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
      event_loop,
      std::make_unique<aos::logger::RenamableFileBackend>(
          absl::StrCat(log_name.value(), "/"), absl::GetFlag(FLAGS_direct)));
}

int main(int argc, char *argv[]) {
  absl::SetProgramUsageMessage(
      "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(absl::GetFlag(FLAGS_config));

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

  aos::Fetcher<aos::util::FilesystemStatus> filesystem_status =
      event_loop.MakeFetcher<aos::util::FilesystemStatus>("/aos");

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

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

  LOG(INFO) << "Starting image_logger; will wait on joystick enabled to start "
               "logging";
  event_loop.OnRun([]() {
    errno = 0;
    setpriority(PRIO_PROCESS, 0, -20);
    PCHECK(errno == 0) << ": Renicing to -20 failed.";
  });

  event_loop.MakeWatcher(
      "/imu/aos", [&](const aos::JoystickState &joystick_state) {
        const auto timestamp = event_loop.context().monotonic_event_time;
        filesystem_status.Fetch();

        // Store the last time we got disabled
        if (enabled && !joystick_state.enabled()) {
          last_disable_time = timestamp;
        }
        enabled = joystick_state.enabled();

        bool enough_space = true;

        if (filesystem_status.get() != nullptr) {
          enough_space = false;
          for (const aos::util::Filesystem *fs :
               *filesystem_status->filesystems()) {
            CHECK(fs->has_path());
            if (fs->path()->string_view() == "/") {
              if (fs->free_space() > 50ull * 1024ull * 1024ull * 1024ull) {
                enough_space = true;
              }
            }
          }
        }

        const bool should_be_logging =
            (enabled ||
             timestamp <
                 last_disable_time + std::chrono::duration<double>(
                                         absl::GetFlag(FLAGS_disabled_time))) &&
            enough_space;

        if (!logging && should_be_logging) {
          auto log_namer = MakeLogNamer(&event_loop);
          if (log_namer == nullptr) {
            return;
          }

          // Start logging if we just got enabled
          LOG(INFO) << "Starting logging";
          logger.StartLogging(std::move(log_namer));
          logging = true;
          last_rotation_time = event_loop.monotonic_now();
        } else if (logging && !should_be_logging) {
          // 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;
}
