//
// Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
//

#include "time.hpp"

namespace sf {

namespace internal {

int32_t getHourFromSeconds(int64_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] / SECONDS_PER_HOUR;
}

int32_t getHourFromSeconds(int32_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] / SECONDS_PER_HOUR;
}

int32_t getMinuteFromSeconds(int64_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] % SECONDS_PER_HOUR / SECONDS_PER_MINUTE;
}

int32_t getMinuteFromSeconds(int32_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] % SECONDS_PER_HOUR / SECONDS_PER_MINUTE;
}

int32_t getSecondFromSeconds(int64_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] % SECONDS_PER_MINUTE;
}

int32_t getSecondFromSeconds(int32_t seconds, int32_t scale) {
  return seconds / powTenSB4[scale] % SECONDS_PER_MINUTE;
}

int32_t getMicrosecondFromSeconds(int64_t seconds, int32_t scale) {
  int32_t microsec = seconds % powTenSB4[scale];
  return scale > PYTHON_DATETIME_TIME_MICROSEC_DIGIT
             ? microsec /=
               powTenSB4[scale - PYTHON_DATETIME_TIME_MICROSEC_DIGIT]
             : microsec *=
               powTenSB4[PYTHON_DATETIME_TIME_MICROSEC_DIGIT - scale];
}

TimeSpec::TimeSpec(int64_t units, int32_t scale) {
  if (scale == 0) {
    seconds = units;
    microseconds = 0;
  } else if (scale == 6) {
    seconds = 0;
    microseconds = units;
  } else if (scale > 6) {
    seconds = 0;
    const int divider = internal::powTenSB4[scale - 6];
    if (units < 0) {
      units -= divider - 1;
    }
    microseconds = units / divider;
  } else {
    seconds = units / internal::powTenSB4[scale];
    int64_t fractions = std::abs(units % internal::powTenSB4[scale]);
    microseconds = fractions * internal::powTenSB4[6 - scale];
    if (units < 0) {
      microseconds = -microseconds;
    }
  }
}

}  // namespace internal
}  // namespace sf
