// ========================================================================================
// IMPORTANT: You should not edit this file
// ========================================================================================

#include <iostream>
#include <iomanip>
#include <cassert>
#include <cstdint>

#include "timestamp.h"

// Add the specified number of seconds to the TimeStamp.
// Overflow seconds to minutes, hours, and days as necessary 
void TimeStamp::addMilliseconds(int ms) {
  assert (ms >= 0);
  milliseconds += ms;
  while (milliseconds >= 1000) { milliseconds -= 1000; seconds++; }
  while (seconds >= 60) { seconds -= 60; minutes++; }
  while (minutes >= 60) { minutes -= 60; hours++; }
  while (hours >= 24) { hours -= 24; days++; }
}

uint64_t TimeStamp::getTotalMilliseconds() const {
  uint64_t answer = 0;
  answer += milliseconds;
  answer += seconds * 1000;
  answer += minutes * 60 * 1000;
  answer += hours * 60 * 60 * 1000;
  answer += days * 24 * 60 * 60 * 1000;
  return answer;
}

// Convert each TimeStamp to milliseconds, then subtract
uint64_t elapsedMilliseconds(const TimeStamp &a, const TimeStamp &b) {
  assert (a <= b);
  uint64_t left  = a.getTotalMilliseconds();
  uint64_t right = b.getTotalMilliseconds();
  if (!(left <= right)) {
    std::cout << "       a " << a << " b " << b << std::endl;
    std::cout << "       " << left << " " << right << std::endl;
  }
  assert (left <= right);
  return right - left;
}

// For sorting TimeStamp objects
bool operator==(const TimeStamp &a, const TimeStamp &b) {
  uint64_t left  = a.getTotalMilliseconds();
  uint64_t right = b.getTotalMilliseconds();
  return left == right;
}

// For sorting TimeStamp objects
bool operator<(const TimeStamp &a, const TimeStamp &b) {
  uint64_t left  = a.getTotalMilliseconds();
  uint64_t right = b.getTotalMilliseconds();
  return left < right;
}

bool operator<=(const TimeStamp &a, const TimeStamp &b) {
  return a < b || a == b;
}

// For sorting TimeStamp objects
bool operator>(const TimeStamp &a, const TimeStamp &b) {
  uint64_t left  = a.getTotalMilliseconds();
  uint64_t right = b.getTotalMilliseconds();
  return left > right;
}

bool operator>=(const TimeStamp &a, const TimeStamp &b) {
  return a > b || a == b;
}


// For printing TimeStamp objects
std::ostream& operator<<(std::ostream &ostr, const TimeStamp &a) {
  ostr << std::right << std::setfill('0')
       << std::setw(2) << a.getHours() << ":"
       << std::setw(2) << a.getMinutes() << ":"
       << std::setw(2) << a.getSeconds() << "."
       << std::setw(3) << a.getMilliseconds()
       << std::setfill(' ');
  return ostr;
}
