#include <stdio.h>

#include <chrono>
#include <memory>

#include "aos/common/logging/logging.h"
#include "aos/common/logging/queue_logging.h"
#include "aos/common/time.h"
#include "aos/common/util/phased_loop.h"
#include "aos/common/util/trapezoid_profile.h"
#include "frc971/autonomous/auto.q.h"
#include "frc971/control_loops/drivetrain/drivetrain.q.h"
#include "y2015/actors/drivetrain_actor.h"
#include "y2015/actors/held_to_lift_actor.h"
#include "y2015/actors/pickup_actor.h"
#include "y2015/actors/stack_actor.h"
#include "y2015/autonomous/auto.q.h"
#include "y2015/constants.h"
#include "y2015/control_loops/claw/claw.q.h"
#include "y2015/control_loops/fridge/fridge.q.h"

using ::frc971::control_loops::drivetrain_queue;
using ::y2015::control_loops::claw_queue;
using ::y2015::control_loops::fridge::fridge_queue;

namespace chrono = ::std::chrono;
namespace this_thread = ::std::this_thread;
using ::aos::monotonic_clock;

namespace y2015 {
namespace autonomous {

constexpr double kClawAutoVelocity = 3.00;
constexpr double kClawAutoAcceleration = 6.0;
constexpr double kAngleEpsilon = 0.10;
const double kClawTotePackAngle = 0.90;
const double kArmRaiseLowerClearance = -0.08;
const double kClawStackClearance = 0.55;
const double kStackUpHeight = 0.60;
const double kStackUpArm = 0.0;

struct ProfileParams {
  double velocity;
  double acceleration;
};

namespace time = ::aos::time;

static double left_initial_position, right_initial_position;

bool ShouldExitAuto() {
  ::frc971::autonomous::autonomous.FetchLatest();
  bool ans = !::frc971::autonomous::autonomous->run_auto;
  if (ans) {
    LOG(INFO, "Time to exit auto mode\n");
  }
  return ans;
}

void StopDrivetrain() {
  LOG(INFO, "Stopping the drivetrain\n");
  drivetrain_queue.goal.MakeWithBuilder()
      .control_loop_driving(true)
      .left_goal(left_initial_position)
      .left_velocity_goal(0)
      .right_goal(right_initial_position)
      .right_velocity_goal(0)
      .quickturn(false)
      .Send();
}

void ResetDrivetrain() {
  LOG(INFO, "resetting the drivetrain\n");
  drivetrain_queue.goal.MakeWithBuilder()
      .control_loop_driving(false)
      //.highgear(false)
      .steering(0.0)
      .throttle(0.0)
      .left_goal(left_initial_position)
      .left_velocity_goal(0)
      .right_goal(right_initial_position)
      .right_velocity_goal(0)
      .Send();
}

void WaitUntilDoneOrCanceled(
    ::std::unique_ptr<aos::common::actions::Action> action) {
  if (!action) {
    LOG(ERROR, "No action, not waiting\n");
    return;
  }
  ::aos::time::PhasedLoop phased_loop(chrono::milliseconds(5),
                                      chrono::microseconds(2500));
  while (true) {
    // Poll the running bit and auto done bits.
    phased_loop.SleepUntilNext();
    if (!action->Running() || ShouldExitAuto()) {
      return;
    }
  }
}

void StepDrive(double distance, double theta) {
  double left_goal = (left_initial_position + distance -
                      theta * constants::GetValues().turn_width / 2.0);
  double right_goal = (right_initial_position + distance +
                       theta * constants::GetValues().turn_width / 2.0);
  drivetrain_queue.goal.MakeWithBuilder()
      .control_loop_driving(true)
      .left_goal(left_goal)
      .right_goal(right_goal)
      .left_velocity_goal(0.0)
      .right_velocity_goal(0.0)
      .Send();
  left_initial_position = left_goal;
  right_initial_position = right_goal;
}

void WaitUntilNear(double distance) {
  while (true) {
    if (ShouldExitAuto()) return;
    drivetrain_queue.status.FetchAnother();
    double left_error =
        ::std::abs(left_initial_position -
                   drivetrain_queue.status->estimated_left_position);
    double right_error =
        ::std::abs(right_initial_position -
                   drivetrain_queue.status->estimated_right_position);
    const double kPositionThreshold = 0.05 + distance;
    if (right_error < kPositionThreshold && left_error < kPositionThreshold) {
      LOG(INFO, "At the goal\n");
      return;
    }
  }
}

const ProfileParams kFastDrive = {2.0, 3.5};
const ProfileParams kFastKnockDrive = {2.0, 3.0};
const ProfileParams kStackingSecondDrive = {2.0, 1.5};
const ProfileParams kFastTurn = {3.0, 10.0};
const ProfileParams kStackingFirstTurn = {1.0, 1.0};
const ProfileParams kStackingSecondTurn = {2.0, 6.0};
const ProfileParams kComboTurn = {1.2, 8.0};
const ProfileParams kRaceTurn = {4.0, 10.0};
const ProfileParams kRaceDrive = {2.0, 2.0};
const ProfileParams kRaceBackupDrive = {2.0, 5.0};

::std::unique_ptr<::y2015::actors::DrivetrainAction> SetDriveGoal(
    double distance, const ProfileParams drive_params, double theta = 0,
    const ProfileParams &turn_params = kFastTurn) {
  LOG(INFO, "Driving to %f\n", distance);

  ::y2015::actors::DrivetrainActionParams params;
  params.left_initial_position = left_initial_position;
  params.right_initial_position = right_initial_position;
  params.y_offset = distance;
  params.theta_offset = theta;
  params.maximum_turn_acceleration = turn_params.acceleration;
  params.maximum_turn_velocity = turn_params.velocity;
  params.maximum_velocity = drive_params.velocity;
  params.maximum_acceleration = drive_params.acceleration;
  auto drivetrain_action = actors::MakeDrivetrainAction(params);

  drivetrain_action->Start();
  left_initial_position +=
      distance - theta * constants::GetValues().turn_width / 2.0;
  right_initial_position +=
      distance + theta * constants::GetValues().turn_width / 2.0;
  return drivetrain_action;
}

const ProfileParams kFridgeYProfile{1.0, 4.0};
const ProfileParams kFridgeXProfile{1.0, 2.0};
const ProfileParams kFridgeFastXProfile{1.2, 5.0};

static double fridge_goal_x = 0.0;
static double fridge_goal_y = 0.0;

void MoveFridge(double x, double y, bool grabbers, const ProfileParams x_params,
                const ProfileParams y_params) {
  auto new_fridge_goal = fridge_queue.goal.MakeMessage();
  new_fridge_goal->profiling_type = 1;

  new_fridge_goal->max_y_velocity = y_params.velocity;
  new_fridge_goal->max_y_acceleration = y_params.acceleration;
  new_fridge_goal->y = y;
  fridge_goal_y = y;
  new_fridge_goal->y_velocity = 0.0;

  new_fridge_goal->max_x_velocity = x_params.velocity;
  new_fridge_goal->max_x_acceleration = x_params.acceleration;
  new_fridge_goal->x = x;
  fridge_goal_x = x;
  new_fridge_goal->x_velocity = 0.0;

  new_fridge_goal->grabbers.top_front = grabbers;
  new_fridge_goal->grabbers.top_back = grabbers;
  new_fridge_goal->grabbers.bottom_front = grabbers;
  new_fridge_goal->grabbers.bottom_back = grabbers;

  if (!new_fridge_goal.Send()) {
    LOG(ERROR, "Sending fridge goal failed.\n");
    return;
  }
}

void WaitForFridge() {
  while (true) {
    if (ShouldExitAuto()) return;
    fridge_queue.status.FetchAnother();

    constexpr double kProfileError = 1e-5;
    constexpr double kXEpsilon = 0.03, kYEpsilon = 0.03;

    if (fridge_queue.status->state != 4) {
      LOG(ERROR, "Fridge no longer running, aborting action\n");
      return;
    }

    if (::std::abs(fridge_queue.status->goal_x - fridge_goal_x) <
            kProfileError &&
        ::std::abs(fridge_queue.status->goal_y - fridge_goal_y) <
            kProfileError &&
        ::std::abs(fridge_queue.status->goal_x_velocity) < kProfileError &&
        ::std::abs(fridge_queue.status->goal_y_velocity) < kProfileError) {
      LOG(INFO, "Profile done.\n");
      if (::std::abs(fridge_queue.status->x - fridge_goal_x) <
              kXEpsilon &&
          ::std::abs(fridge_queue.status->y - fridge_goal_y) <
              kYEpsilon) {
        LOG(INFO, "Near goal, done.\n");
        return;
      }
    }
  }
}

void InitializeEncoders() {
  drivetrain_queue.status.FetchAnother();
  left_initial_position = drivetrain_queue.status->estimated_left_position;
  right_initial_position = drivetrain_queue.status->estimated_right_position;
}

void WaitForClawZero() {
  LOG(INFO, "Waiting for claw to zero.\n");
  while (true) {
    control_loops::claw_queue.status.FetchAnother();
    LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);
    if (control_loops::claw_queue.status->zeroed) {
      LOG(INFO, "Claw zeroed\n");
      return;
    }

    if (ShouldExitAuto()) return;
  }
}

void WaitForFridgeZero() {
  LOG(INFO, "Waiting for claw to zero.\n");
  while (true) {
    fridge_queue.status.FetchAnother();
    LOG_STRUCT(DEBUG, "Got fridge status", *fridge_queue.status);
    if (fridge_queue.status->zeroed) {
      LOG(INFO, "Fridge zeroed\n");
      return;
    }

    if (ShouldExitAuto()) return;
  }
}

constexpr ProfileParams kDefaultClawParams = {kClawAutoVelocity,
                                              kClawAutoAcceleration};

// Move the claw in a very small number of cycles.
constexpr ProfileParams kInstantaneousClaw = {100.0, 100.0};
constexpr ProfileParams kFastClaw = {8.0, 20.0};

void SetClawStateNoWait(double angle, double intake_voltage,
                        double rollers_closed,
                        const ProfileParams &claw_params = kDefaultClawParams) {
  auto message = control_loops::claw_queue.goal.MakeMessage();
  message->angle = angle;
  message->max_velocity = claw_params.velocity;
  message->max_acceleration = claw_params.acceleration;
  message->angular_velocity = 0.0;
  message->intake = intake_voltage;
  message->rollers_closed = rollers_closed;

  LOG_STRUCT(DEBUG, "Sending claw goal", *message);
  message.Send();
}

void SetClawState(double angle, double intake_voltage, double rollers_closed,
                  const ProfileParams &claw_params = kDefaultClawParams) {
  SetClawStateNoWait(angle, intake_voltage, rollers_closed, claw_params);
  while (true) {
    control_loops::claw_queue.status.FetchAnother();
    const double current_angle = control_loops::claw_queue.status->angle;
    LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);

    // I believe all we can care about here is the angle. Other values will
    // either be set or not, but there is nothing we can do about it. If it
    // never gets there we do not care, auto is over for us.
    if (::std::abs(current_angle - angle) < kAngleEpsilon) {
      break;
    }
    if (ShouldExitAuto()) return;
  }
}

void TripleCanAuto() {
  ::std::unique_ptr<::y2015::actors::DrivetrainAction> drive;
  ::std::unique_ptr<::y2015::actors::PickupAction> pickup;
  ::std::unique_ptr<::y2015::actors::StackAction> stack;
  ::std::unique_ptr<::y2015::actors::HeldToLiftAction> lift;

  actors::PickupParams pickup_params;
  // Lift to here initially.
  pickup_params.pickup_angle = 0.9;
  // Start sucking here
  pickup_params.suck_angle = 0.8;
  // Go back down to here to finish sucking.
  pickup_params.suck_angle_finish = 0.4;
  // Pack the box back in here.
  pickup_params.pickup_finish_angle = kClawTotePackAngle;
  pickup_params.intake_time = 0.70;
  pickup_params.intake_voltage = 7.0;

  if (ShouldExitAuto()) return;
  InitializeEncoders();
  ResetDrivetrain();

  WaitForClawZero();
  WaitForFridgeZero();

  // Initialize the fridge.
  MoveFridge(0.0, 0.3, true, kFridgeXProfile, kFridgeYProfile);

  LOG(INFO, "Lowering claw into position.\n");
  SetClawState(0.0, 2.0, false, kInstantaneousClaw);

  LOG(INFO, "Sucking in tote.\n");
  SetClawState(0.0, 6.0, true, kInstantaneousClaw);

  this_thread::sleep_for(chrono::milliseconds(700));
  LOG(INFO, "Done sucking in tote\n");

  // Now pick it up
  pickup = actors::MakePickupAction(pickup_params);
  pickup->Start();

  this_thread::sleep_for(chrono::milliseconds(900));
  // Start turning.
  LOG(INFO, "Turning in place\n");
  drive = SetDriveGoal(0.0, kFastDrive, -0.23, kStackingFirstTurn);

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Now driving next to the can\n");
  drive = SetDriveGoal(0.60, kFastDrive);

  WaitUntilDoneOrCanceled(::std::move(pickup));
  if (ShouldExitAuto()) return;

  // Now grab it in the fridge.
  {
    actors::StackParams params;

    params.claw_out_angle = kClawTotePackAngle;
    params.bottom = 0.020;
    params.only_place = false;
    params.arm_clearance = kArmRaiseLowerClearance;
    params.over_box_before_place_height = 0.39;

    stack = actors::MakeStackAction(params);
    stack->Start();
  }
  WaitUntilDoneOrCanceled(::std::move(stack));
  if (ShouldExitAuto()) return;

  // Lower the claw to knock the tote.
  LOG(INFO, "Lowering the claw to knock the tote\n");
  SetClawStateNoWait(0.0, 0.0, true, kFastClaw);

  this_thread::sleep_for(chrono::milliseconds(100));
  if (ShouldExitAuto()) return;

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Knocking the can over\n");
  drive = SetDriveGoal(0.40, kFastKnockDrive, 1.05, kComboTurn);
  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;
  {
    actors::HeldToLiftParams params;
    params.arm_clearance = kArmRaiseLowerClearance;
    params.clamp_pause_time = 0.1;
    params.before_lift_settle_time = 0.1;
    params.bottom_height = 0.020;
    params.claw_out_angle = kClawStackClearance;
    params.lift_params.lift_height = kStackUpHeight;
    params.lift_params.lift_arm = kStackUpArm;
    params.lift_params.second_lift = false;

    lift = actors::MakeHeldToLiftAction(params);
    lift->Start();
  }

  LOG(INFO, "Turning back to aim\n");
  drive = SetDriveGoal(0.0, kFastDrive, -0.70);
  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  SetClawStateNoWait(0.0, 4.0, false, kFastClaw);
  LOG(INFO, "Now driving the second tote\n");
  drive = SetDriveGoal(1.05, kFastDrive);

  // Wait until we are almost at the tote, and then start intaking.
  WaitUntilNear(0.35);

  SetClawState(0.0, 6.0, true, kFastClaw);
  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  if (ShouldExitAuto()) return;
  this_thread::sleep_for(chrono::milliseconds(300));
  if (ShouldExitAuto()) return;

  SetClawStateNoWait(0.0, 4.0, true, kFastClaw);
  if (ShouldExitAuto()) return;
  this_thread::sleep_for(chrono::milliseconds(100));

  WaitUntilDoneOrCanceled(::std::move(lift));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Done sucking in tote\n");
  SetClawState(0.0, 0.0, true, kFastClaw);
  if (ShouldExitAuto()) return;

  // Now pick it up
  pickup = actors::MakePickupAction(pickup_params);
  pickup->Start();

  this_thread::sleep_for(chrono::seconds(1));
  if (ShouldExitAuto()) return;

  // Start turning.
  LOG(INFO, "Turning in place\n");
  drive = SetDriveGoal(0.0, kStackingSecondDrive, -0.40, kStackingSecondTurn);

  WaitUntilDoneOrCanceled(::std::move(pickup));
  if (ShouldExitAuto()) return;

  // Now grab it in the fridge.
  {
    actors::StackParams params;

    params.claw_out_angle = kClawTotePackAngle;
    params.bottom = 0.020;
    params.only_place = false;
    params.arm_clearance = kArmRaiseLowerClearance;
    params.over_box_before_place_height = 0.39;

    stack = actors::MakeStackAction(params);
    stack->Start();
  }

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;
  LOG(INFO, "Driving next to the can.\n");
  drive = SetDriveGoal(0.65, kStackingSecondDrive);

  WaitUntilDoneOrCanceled(::std::move(stack));
  if (ShouldExitAuto()) return;

  // Lower the claw to knock the tote.
  LOG(INFO, "Lowering the claw to knock the tote\n");
  SetClawStateNoWait(0.0, 0.0, true, kFastClaw);

  // Lift the fridge.
  MoveFridge(0.0, 0.3, true, kFridgeXProfile, kFridgeYProfile);

  this_thread::sleep_for(chrono::milliseconds(100));
  if (ShouldExitAuto()) return;

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Knocking the can over\n");
  drive = SetDriveGoal(0.40, kFastKnockDrive, 1.05, kComboTurn);
  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Turning back to aim\n");
  drive = SetDriveGoal(0.0, kFastDrive, -0.60);
  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;


  SetClawStateNoWait(0.0, 4.0, false, kFastClaw);
  LOG(INFO, "Now driving to the last tote\n");
  drive = SetDriveGoal(1.05, kFastDrive);
  WaitUntilNear(0.05);

  SetClawState(0.0, 7.0, true, kFastClaw);
  if (ShouldExitAuto()) return;

  this_thread::sleep_for(chrono::milliseconds(200));
  if (ShouldExitAuto()) return;

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;
  SetClawState(0.0, 6.0, true, kFastClaw);

  LOG(INFO, "Racing over\n");
  //StepDrive(2.5, -1.4);
  drive = SetDriveGoal(2.5, kRaceDrive, -1.4, kRaceTurn);

  this_thread::sleep_for(chrono::milliseconds(500));

  LOG(INFO, "Moving totes out\n");
  MoveFridge(0.6, 0.32, true, kFridgeXProfile, kFridgeYProfile);

  WaitForFridge();
  if (ShouldExitAuto()) return;

  LOG(INFO, "Lowering totes\n");
  MoveFridge(0.6, 0.15, false, kFridgeXProfile, kFridgeYProfile);

  WaitForFridge();
  if (ShouldExitAuto()) return;

  this_thread::sleep_for(chrono::milliseconds(100));

  if (ShouldExitAuto()) return;

  LOG(INFO, "Retracting\n");
  MoveFridge(0.0, 0.10, false, kFridgeFastXProfile, kFridgeYProfile);

  SetClawState(0.0, 0.0, false, kFastClaw);

  if (ShouldExitAuto()) return;

  WaitUntilDoneOrCanceled(::std::move(drive));
  if (ShouldExitAuto()) return;

  LOG(INFO, "Backing away to let the stack ago\n");
  drive = SetDriveGoal(-0.1, kRaceBackupDrive);
  WaitUntilDoneOrCanceled(::std::move(drive));

  WaitForFridge();
  if (ShouldExitAuto()) return;
}

void GrabberForTime(double voltage, monotonic_clock::duration wait_time) {
  monotonic_clock::time_point now = monotonic_clock::now();
  monotonic_clock::time_point end_time = now + wait_time;
  LOG(INFO, "Starting to grab at %f for %f seconds\n", voltage,
      chrono::duration_cast<chrono::duration<double>>(wait_time).count());
  ::aos::time::PhasedLoop phased_loop(chrono::milliseconds(5),
                                      chrono::microseconds(2500));
  while (true) {
    autonomous::can_control.MakeWithBuilder().can_voltage(voltage).Send();
    // Poll the running bit and auto done bits.
    if (ShouldExitAuto()) {
      return;
    }
    if (monotonic_clock::now() > end_time) {
      LOG(INFO, "Done grabbing\n");
      return;
    }
    phased_loop.SleepUntilNext();
  }
}

void CanGrabberAuto() {
  ResetDrivetrain();
  GrabberForTime(12.0, chrono::milliseconds(180));
  if (ShouldExitAuto()) return;

  //GrabberForTime(4.0, chrono::milliseconds(100));
  if (ShouldExitAuto()) return;
  InitializeEncoders();
  ResetDrivetrain();
  if (ShouldExitAuto()) return;
  drivetrain_queue.goal.MakeWithBuilder()
      .control_loop_driving(true)
      //.highgear(false)
      .steering(0.0)
      .throttle(0.0)
      .left_goal(left_initial_position + 1.5)
      .left_velocity_goal(0)
      .right_goal(right_initial_position + 1.5)
      .right_velocity_goal(0)
      .Send();
  GrabberForTime(12.0, chrono::milliseconds(20));

  GrabberForTime(4.0, chrono::seconds(14));
  if (ShouldExitAuto()) return;
}

void HandleAuto() {
  monotonic_clock::time_point start_time = monotonic_clock::now();
  LOG(INFO, "Starting auto mode at %f\n",
      chrono::duration_cast<chrono::duration<double>>(
          start_time.time_since_epoch()).count());
  //TripleCanAuto();
  CanGrabberAuto();
}

}  // namespace autonomous
}  // namespace y2015
