#include "opencv2/calib3d.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include "aos/events/logging/log_reader.h"
#include "aos/events/simulated_event_loop.h"
#include "aos/init.h"
#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
#include "frc971/input/joystick_state_generated.h"
#include "frc971/vision/vision_generated.h"
#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
#include "y2022/vision/blob_detector.h"

ABSL_FLAG(std::string, pi, "pi3", "Node name to replay.");
ABSL_FLAG(std::string, image_save_prefix, "/tmp/img",
          "Prefix to use for saving images from the logfile.");
ABSL_FLAG(bool, display, false, "If true, display the images with a timeout.");
ABSL_FLAG(bool, detected_only, false,
          "If true, only write images which had blobs (unfiltered) detected");
ABSL_FLAG(bool, filtered_only, false,
          "If true, only write images which had blobs (filtered) detected");
ABSL_FLAG(bool, match_timestamps, false,
          "If true, name the files based on the time since the robot was "
          "enabled (match start). Only consider images during this time");
ABSL_FLAG(std::string, logger_pi_log, "/tmp/logger_pi/",
          "Path to logger pi log");
ABSL_FLAG(std::string, roborio_log, "/tmp/roborio/", "Path to roborio log");

namespace y2022::vision {
namespace {

using aos::monotonic_clock;
namespace superstructure = control_loops::superstructure;

// Information to extract from the roborio log
struct ReplayData {
  monotonic_clock::time_point match_start;
  monotonic_clock::time_point match_end;
  std::map<monotonic_clock::time_point, bool> robot_moving;
  std::map<monotonic_clock::time_point, superstructure::SuperstructureState>
      superstructure_states;
};

// Extract the useful data from the roborio log to be used for naming images
void ReplayRoborio(ReplayData *data) {
  data->match_start = monotonic_clock::min_time;
  data->match_end = monotonic_clock::min_time;

  // Open logfiles
  aos::logger::LogReader reader(aos::logger::SortParts(
      aos::logger::FindLogs(absl::GetFlag(FLAGS_roborio_log))));
  reader.Register();
  const aos::Node *roborio =
      aos::configuration::GetNode(reader.configuration(), "roborio");

  std::unique_ptr<aos::EventLoop> event_loop =
      reader.event_loop_factory()->MakeEventLoop("roborio", roborio);

  auto joystick_state_fetcher =
      event_loop->MakeFetcher<aos::JoystickState>("/roborio/aos");
  auto drivetrain_status_fetcher =
      event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
          "/drivetrain");
  auto superstructure_status_fetcher =
      event_loop->MakeFetcher<superstructure::Status>("/superstructure");

  // Periodically check if the robot state updated
  event_loop->AddPhasedLoop(
      [&](int) {
        // Find the match start and end times
        if (joystick_state_fetcher.Fetch()) {
          if (data->match_start == monotonic_clock::min_time &&
              joystick_state_fetcher->enabled()) {
            data->match_start =
                joystick_state_fetcher.context().monotonic_event_time;
          } else {
            if (data->match_end == monotonic_clock::min_time &&
                data->match_start != monotonic_clock::min_time &&
                !joystick_state_fetcher->autonomous() &&
                !joystick_state_fetcher->enabled()) {
              data->match_end =
                  joystick_state_fetcher.context().monotonic_event_time;
            }
          }
        }

        // Add whether the robot was moving at a non-negligible speed to
        // the image name for debugging.
        drivetrain_status_fetcher.Fetch();
        if (drivetrain_status_fetcher.get()) {
          // If the robot speed was atleast this (m/s), it is
          // considered moving.
          constexpr double kMinMovingRobotSpeed = 0.5;
          data->robot_moving[drivetrain_status_fetcher.context()
                                 .monotonic_event_time] =
              (std::abs(drivetrain_status_fetcher->robot_speed()) >=
               kMinMovingRobotSpeed);
        }

        superstructure_status_fetcher.Fetch();
        if (superstructure_status_fetcher.get()) {
          data->superstructure_states[superstructure_status_fetcher.context()
                                          .monotonic_event_time] =
              superstructure_status_fetcher->state();
        }
      },
      std::chrono::milliseconds(50));
  reader.event_loop_factory()->Run();
}

template <typename T>
T ClosestElement(const std::map<monotonic_clock::time_point, T> &map,
                 monotonic_clock::time_point now) {
  T closest;

  // The closest element is either the one right above it, or the element before
  // that one
  auto closest_it = map.lower_bound(now);
  // Handle the case where now is greater than all times in the map
  if (closest_it == map.cend()) {
    closest_it--;
    closest = closest_it->second;
  } else {
    // Start off with the closest as the first after now
    closest = closest_it->second;
    const monotonic_clock::duration after_duration = closest_it->first - now;
    closest_it--;

    // If there is a time before, check if that's closer to now
    if (closest_it != map.cbegin()) {
      const monotonic_clock::duration before_duration = now - closest_it->first;
      if (before_duration < after_duration) {
        closest = closest_it->second;
      }
    }
  }

  return closest;
}

// Extract images from the pi logs
void ReplayPi(const ReplayData &data) {
  if (absl::GetFlag(FLAGS_match_timestamps)) {
    CHECK_NE(data.match_start, monotonic_clock::min_time)
        << "Can't use match timestamps if match never started";
    CHECK_NE(data.match_end, monotonic_clock::min_time)
        << "Can't use match timestamps if match never ended";
  }

  // Open logfiles
  aos::logger::LogReader reader(aos::logger::SortParts(
      aos::logger::FindLogs(absl::GetFlag(FLAGS_logger_pi_log))));
  reader.Register();
  const aos::Node *pi = aos::configuration::GetNode(reader.configuration(),
                                                    absl::GetFlag(FLAGS_pi));

  std::unique_ptr<aos::EventLoop> event_loop =
      reader.event_loop_factory()->MakeEventLoop("player", pi);

  LOG(INFO) << "Match start: " << data.match_start
            << ", match end: " << data.match_end;

  size_t nonmatch_image_count = 0;

  event_loop->MakeWatcher(
      "/camera/decimated", [&](const frc971::vision::CameraImage &image) {
        const auto match_start = data.match_start;
        // Find the closest robot moving and superstructure state to now
        const bool robot_moving =
            ClosestElement(data.robot_moving, event_loop->monotonic_now());
        const auto superstructure_state = ClosestElement(
            data.superstructure_states, event_loop->monotonic_now());

        if (absl::GetFlag(FLAGS_match_timestamps)) {
          if (event_loop->monotonic_now() < data.match_start) {
            // Ignore prematch images if we only care about ones during the
            // match
            return;
          } else if (event_loop->monotonic_now() >= data.match_end) {
            // We're done if the match is over and we only wanted match images
            reader.event_loop_factory()->Exit();
            return;
          }
        }

        // Create color image:
        cv::Mat image_color_mat(cv::Size(image.cols(), image.rows()), CV_8UC2,
                                (void *)image.data()->data());
        cv::Mat image_mat(cv::Size(image.cols(), image.rows()), CV_8UC3);
        cv::cvtColor(image_color_mat, image_mat, cv::COLOR_YUV2BGR_YUYV);

        bool use_image = true;
        if (absl::GetFlag(FLAGS_detected_only) ||
            absl::GetFlag(FLAGS_filtered_only)) {
          // TODO(milind): if adding target estimation here in the future,
          // undistortion is needed
          BlobDetector::BlobResult blob_result;
          BlobDetector::ExtractBlobs(image_mat, &blob_result);

          use_image = ((absl::GetFlag(FLAGS_filtered_only)
                            ? blob_result.filtered_blobs.size()
                            : blob_result.unfiltered_blobs.size()) > 0);
        }

        if (use_image) {
          if (!absl::GetFlag(FLAGS_image_save_prefix).empty()) {
            std::stringstream image_name;
            image_name << absl::GetFlag(FLAGS_image_save_prefix);

            if (absl::GetFlag(FLAGS_match_timestamps)) {
              // Add the time since match start into the image for debugging.
              // We can match images with the game recording.
              image_name << "match_"
                         << std::chrono::duration_cast<std::chrono::seconds>(
                                event_loop->monotonic_now() - match_start)
                                .count()
                         << 's';
            } else {
              image_name << nonmatch_image_count++;
            }

            // Add superstructure state to the filename
            if (superstructure_state !=
                superstructure::SuperstructureState::IDLE) {
              std::string superstructure_state_name =
                  superstructure::EnumNameSuperstructureState(
                      superstructure_state);
              std::transform(superstructure_state_name.begin(),
                             superstructure_state_name.end(),
                             superstructure_state_name.begin(),
                             [](char c) { return std::tolower(c); });
              image_name << '_' << superstructure_state_name;
            }

            if (robot_moving) {
              image_name << "_moving";
            }

            image_name << ".png";

            cv::imwrite(image_name.str(), image_mat);
          }
          if (absl::GetFlag(FLAGS_display)) {
            cv::imshow("Display", image_mat);
            cv::waitKey(absl::GetFlag(FLAGS_detected_only) ||
                                absl::GetFlag(FLAGS_filtered_only)
                            ? 10
                            : 1);
          }
        }
      });

  reader.event_loop_factory()->Run();
}

void ViewerMain() {
  ReplayData data;
  ReplayRoborio(&data);
  ReplayPi(data);
}

}  // namespace
}  // namespace y2022::vision

// Quick and lightweight viewer for image logs
int main(int argc, char **argv) {
  aos::InitGoogle(&argc, &argv);
  y2022::vision::ViewerMain();
}
