// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/media/cpp/timeline_rate.h>

#include <zircon/assert.h>

#include <limits>
#include <utility>

namespace media {

namespace {

// Calculates the greatest common denominator (factor) of two values.
template <typename T>
T BinaryGcd(T a, T b) {
  if (a == 0) {
    return b;
  }

  if (b == 0) {
    return a;
  }

  // Remove and count the common factors of 2.
  uint8_t twos;
  for (twos = 0; ((a | b) & 1) == 0; ++twos) {
    a >>= 1;
    b >>= 1;
  }

  // Get rid of the non-common factors of 2 in a. a is non-zero, so this
  // terminates.
  while ((a & 1) == 0) {
    a >>= 1;
  }

  do {
    // Get rid of the non-common factors of 2 in b. b is non-zero, so this
    // terminates.
    while ((b & 1) == 0) {
      b >>= 1;
    }

    // Apply the Euclid subtraction method.
    if (a > b) {
      std::swap(a, b);
    }

    b = b - a;
  } while (b != 0);

  // Multiply in the common factors of two.
  return a << twos;
}

// Reduces the ratio of *numerator and *denominator.
template <typename T>
void ReduceRatio(T* numerator, T* denominator) {
  ZX_DEBUG_ASSERT(numerator != nullptr);
  ZX_DEBUG_ASSERT(denominator != nullptr);
  ZX_DEBUG_ASSERT(*denominator != 0);

  T gcd = BinaryGcd(*numerator, *denominator);

  if (gcd == 0) {
    *denominator = 1;
    return;
  }

  if (gcd == 1) {
    return;
  }

  *numerator = *numerator / gcd;
  *denominator = *denominator / gcd;
}

template void ReduceRatio<uint64_t>(uint64_t* numerator, uint64_t* denominator);
template void ReduceRatio<uint32_t>(uint32_t* numerator, uint32_t* denominator);

// Scales a uint64_t value by the ratio of two uint32_t values. If round_up is
// true, the result is rounded up rather than down. overflow is set to indicate
// overflow.
uint64_t ScaleUInt64(uint64_t value, uint32_t subject_delta, uint32_t reference_delta,
                     bool round_up, bool* overflow) {
  ZX_DEBUG_ASSERT(reference_delta != 0u);
  ZX_DEBUG_ASSERT(overflow != nullptr);

  constexpr uint64_t kLow32Bits = 0xffffffffu;
  constexpr uint64_t kHigh32Bits = kLow32Bits << 32u;

  // high and low are the product of the subject_delta and the high and low
  // halves
  // (respectively) of value.
  uint64_t high = subject_delta * (value >> 32u);
  uint64_t low = subject_delta * (value & kLow32Bits);
  // Ignoring overflow and remainder, the result we want is:
  // ((high << 32) + low) / reference_delta.

  // Move the high end of low into the low end of high.
  high += low >> 32u;
  low = low & kLow32Bits;
  // Ignoring overflow and remainder, the result we want is still:
  // ((high << 32) + low) / reference_delta.

  // When we divide high by reference_delta, there'll be a remainder. Make
  // that the high end of low, which is currently all zeroes.
  low |= (high % reference_delta) << 32u;

  // Determine if we need to round up when we're done:
  round_up = round_up && (low % reference_delta) != 0;

  // Do the division.
  high /= reference_delta;
  low /= reference_delta;

  // If high's top 32 bits aren't all zero, we have overflow.
  if (high & kHigh32Bits) {
    *overflow = true;
    return 0;
  }

  uint64_t result = (high << 32u) | low;
  if (round_up) {
    if (result == std::numeric_limits<int64_t>::max()) {
      *overflow = true;
      return 0;
    }
    ++result;
  }

  *overflow = false;
  return result;
}

}  // namespace

// static
const TimelineRate TimelineRate::Zero = TimelineRate(0, 1);

// static
const TimelineRate TimelineRate::NsPerSecond = TimelineRate(1000000000L, 1);

// static
void TimelineRate::Reduce(uint32_t* subject_delta, uint32_t* reference_delta) {
  ReduceRatio(subject_delta, reference_delta);
}

// static
void TimelineRate::Product(uint32_t a_subject_delta, uint32_t a_reference_delta,
                           uint32_t b_subject_delta, uint32_t b_reference_delta,
                           uint32_t* product_subject_delta, uint32_t* product_reference_delta,
                           bool exact) {
  ZX_DEBUG_ASSERT(a_reference_delta != 0);
  ZX_DEBUG_ASSERT(b_reference_delta != 0);
  ZX_DEBUG_ASSERT(product_subject_delta != nullptr);
  ZX_DEBUG_ASSERT(product_reference_delta != nullptr);

  uint64_t subject_delta = static_cast<uint64_t>(a_subject_delta) * b_subject_delta;
  uint64_t reference_delta = static_cast<uint64_t>(a_reference_delta) * b_reference_delta;

  ReduceRatio(&subject_delta, &reference_delta);

  if (subject_delta > std::numeric_limits<uint32_t>::max() ||
      reference_delta > std::numeric_limits<uint32_t>::max()) {
    ZX_DEBUG_ASSERT(!exact);

    do {
      subject_delta >>= 1;
      reference_delta >>= 1;
    } while (subject_delta > std::numeric_limits<uint32_t>::max() ||
             reference_delta > std::numeric_limits<uint32_t>::max());

    if (reference_delta == 0) {
      // Product is larger than we can represent. Return the largest value we
      // can represent.
      *product_subject_delta = std::numeric_limits<uint32_t>::max();
      *product_reference_delta = 1;
      return;
    }
  }

  *product_subject_delta = static_cast<uint32_t>(subject_delta);
  *product_reference_delta = static_cast<uint32_t>(reference_delta);
}

// static
int64_t TimelineRate::Scale(int64_t value, uint32_t subject_delta, uint32_t reference_delta) {
  static constexpr uint64_t abs_of_min_int64 =
      static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1;

  ZX_DEBUG_ASSERT(reference_delta != 0u);

  bool overflow;

  uint64_t abs_result;

  if (value >= 0) {
    abs_result =
        ScaleUInt64(static_cast<uint64_t>(value), subject_delta, reference_delta, false, &overflow);
  } else if (value == std::numeric_limits<int64_t>::min()) {
    abs_result = ScaleUInt64(abs_of_min_int64, subject_delta, reference_delta, true, &overflow);
  } else {
    abs_result =
        ScaleUInt64(static_cast<uint64_t>(-value), subject_delta, reference_delta, true, &overflow);
  }

  if (overflow) {
    return TimelineRate::kOverflow;
  }

  // Make sure we won't overflow when we cast to int64_t.
  if (abs_result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
    if (value < 0 && abs_result == abs_of_min_int64) {
      return std::numeric_limits<int64_t>::min();
    }
    return TimelineRate::kOverflow;
  }

  return value >= 0 ? static_cast<int64_t>(abs_result) : -static_cast<int64_t>(abs_result);
}

}  // namespace media
