/*
 *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#ifndef RTC_BASE_UNITS_UNIT_BASE_H_
#define RTC_BASE_UNITS_UNIT_BASE_H_

#include <stdint.h>
#include <algorithm>
#include <cmath>
#include <limits>
#include <type_traits>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"

namespace webrtc {
namespace rtc_units_impl {

// UnitBase is a base class for implementing custom value types with a specific
// unit. It provides type safety and commonly useful operations. The underlying
// storage is always an int64_t, it's up to the unit implementation to choose
// what scale it represents.
//
// It's used like:
// class MyUnit: public UnitBase<MyUnit> {...};
//
// Unit_T is the subclass representing the specific unit.
template <class Unit_T>
class UnitBase {
 public:
  UnitBase() = delete;
  static constexpr Unit_T Zero() { return Unit_T(0); }
  static constexpr Unit_T PlusInfinity() { return Unit_T(PlusInfinityVal()); }
  static constexpr Unit_T MinusInfinity() { return Unit_T(MinusInfinityVal()); }

  constexpr bool IsZero() const { return value_ == 0; }
  constexpr bool IsFinite() const { return !IsInfinite(); }
  constexpr bool IsInfinite() const {
    return value_ == PlusInfinityVal() || value_ == MinusInfinityVal();
  }
  constexpr bool IsPlusInfinity() const { return value_ == PlusInfinityVal(); }
  constexpr bool IsMinusInfinity() const {
    return value_ == MinusInfinityVal();
  }

  constexpr bool operator==(const Unit_T& other) const {
    return value_ == other.value_;
  }
  constexpr bool operator!=(const Unit_T& other) const {
    return value_ != other.value_;
  }
  constexpr bool operator<=(const Unit_T& other) const {
    return value_ <= other.value_;
  }
  constexpr bool operator>=(const Unit_T& other) const {
    return value_ >= other.value_;
  }
  constexpr bool operator>(const Unit_T& other) const {
    return value_ > other.value_;
  }
  constexpr bool operator<(const Unit_T& other) const {
    return value_ < other.value_;
  }

 protected:
  template <int64_t value>
  static constexpr Unit_T FromStaticValue() {
    static_assert(value >= 0 || !Unit_T::one_sided, "");
    static_assert(value > MinusInfinityVal(), "");
    static_assert(value < PlusInfinityVal(), "");
    return Unit_T(value);
  }

  template <int64_t fraction_value, int64_t Denominator>
  static constexpr Unit_T FromStaticFraction() {
    static_assert(fraction_value >= 0 || !Unit_T::one_sided, "");
    static_assert(fraction_value > MinusInfinityVal() / Denominator, "");
    static_assert(fraction_value < PlusInfinityVal() / Denominator, "");
    return Unit_T(fraction_value * Denominator);
  }

  template <
      typename T,
      typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
  static Unit_T FromValue(T value) {
    if (Unit_T::one_sided)
      RTC_DCHECK_GE(value, 0);
    RTC_DCHECK_GT(value, MinusInfinityVal());
    RTC_DCHECK_LT(value, PlusInfinityVal());
    return Unit_T(rtc::dchecked_cast<int64_t>(value));
  }
  template <typename T,
            typename std::enable_if<std::is_floating_point<T>::value>::type* =
                nullptr>
  static Unit_T FromValue(T value) {
    if (value == std::numeric_limits<T>::infinity()) {
      return PlusInfinity();
    } else if (value == -std::numeric_limits<T>::infinity()) {
      return MinusInfinity();
    } else {
      RTC_DCHECK(!std::isnan(value));
      return FromValue(rtc::dchecked_cast<int64_t>(value));
    }
  }

  template <
      int64_t Denominator,
      typename T,
      typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
  static Unit_T FromFraction(T value) {
    if (Unit_T::one_sided)
      RTC_DCHECK_GE(value, 0);
    RTC_DCHECK_GT(value, MinusInfinityVal() / Denominator);
    RTC_DCHECK_LT(value, PlusInfinityVal() / Denominator);
    return Unit_T(rtc::dchecked_cast<int64_t>(value * Denominator));
  }
  template <int64_t Denominator,
            typename T,
            typename std::enable_if<std::is_floating_point<T>::value>::type* =
                nullptr>
  static Unit_T FromFraction(T value) {
    return FromValue(value * Denominator);
  }

  template <typename T = int64_t>
  typename std::enable_if<std::is_integral<T>::value, T>::type ToValue() const {
    RTC_DCHECK(IsFinite());
    return rtc::dchecked_cast<T>(value_);
  }
  template <typename T>
  constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
  ToValue() const {
    return IsPlusInfinity()
               ? std::numeric_limits<T>::infinity()
               : IsMinusInfinity() ? -std::numeric_limits<T>::infinity()
                                   : value_;
  }
  template <typename T>
  constexpr T ToValueOr(T fallback_value) const {
    return IsFinite() ? value_ : fallback_value;
  }

  template <int64_t Denominator, typename T = int64_t>
  typename std::enable_if<std::is_integral<T>::value, T>::type ToFraction()
      const {
    RTC_DCHECK(IsFinite());
    if (Unit_T::one_sided) {
      return rtc::dchecked_cast<T>(
          DivRoundPositiveToNearest(value_, Denominator));
    } else {
      return rtc::dchecked_cast<T>(DivRoundToNearest(value_, Denominator));
    }
  }
  template <int64_t Denominator, typename T>
  constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
  ToFraction() const {
    return ToValue<T>() * (1 / static_cast<T>(Denominator));
  }

  template <int64_t Denominator>
  constexpr int64_t ToFractionOr(int64_t fallback_value) const {
    return IsFinite() ? Unit_T::one_sided
                            ? DivRoundPositiveToNearest(value_, Denominator)
                            : DivRoundToNearest(value_, Denominator)
                      : fallback_value;
  }

  template <int64_t Factor, typename T = int64_t>
  typename std::enable_if<std::is_integral<T>::value, T>::type ToMultiple()
      const {
    RTC_DCHECK_GE(ToValue(), std::numeric_limits<T>::min() / Factor);
    RTC_DCHECK_LE(ToValue(), std::numeric_limits<T>::max() / Factor);
    return rtc::dchecked_cast<T>(ToValue() * Factor);
  }
  template <int64_t Factor, typename T>
  constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
  ToMultiple() const {
    return ToValue<T>() * Factor;
  }

  explicit constexpr UnitBase(int64_t value) : value_(value) {}

 private:
  template <class RelativeUnit_T>
  friend class RelativeUnit;

  static inline constexpr int64_t PlusInfinityVal() {
    return std::numeric_limits<int64_t>::max();
  }
  static inline constexpr int64_t MinusInfinityVal() {
    return std::numeric_limits<int64_t>::min();
  }

  Unit_T& AsSubClassRef() { return reinterpret_cast<Unit_T&>(*this); }
  constexpr const Unit_T& AsSubClassRef() const {
    return reinterpret_cast<const Unit_T&>(*this);
  }
  // Assumes that n >= 0 and d > 0.
  static constexpr int64_t DivRoundPositiveToNearest(int64_t n, int64_t d) {
    return (n + d / 2) / d;
  }
  // Assumes that d > 0.
  static constexpr int64_t DivRoundToNearest(int64_t n, int64_t d) {
    return (n + (n >= 0 ? d / 2 : -d / 2)) / d;
  }

  int64_t value_;
};

// Extends UnitBase to provide operations for relative units, that is, units
// that have a meaningful relation between values such that a += b is a
// sensible thing to do. For a,b <- same unit.
template <class Unit_T>
class RelativeUnit : public UnitBase<Unit_T> {
 public:
  Unit_T Clamped(Unit_T min_value, Unit_T max_value) const {
    return std::max(min_value,
                    std::min(UnitBase<Unit_T>::AsSubClassRef(), max_value));
  }
  void Clamp(Unit_T min_value, Unit_T max_value) {
    *this = Clamped(min_value, max_value);
  }
  Unit_T operator+(const Unit_T other) const {
    if (this->IsPlusInfinity() || other.IsPlusInfinity()) {
      RTC_DCHECK(!this->IsMinusInfinity());
      RTC_DCHECK(!other.IsMinusInfinity());
      return this->PlusInfinity();
    } else if (this->IsMinusInfinity() || other.IsMinusInfinity()) {
      RTC_DCHECK(!this->IsPlusInfinity());
      RTC_DCHECK(!other.IsPlusInfinity());
      return this->MinusInfinity();
    }
    return UnitBase<Unit_T>::FromValue(this->ToValue() + other.ToValue());
  }
  Unit_T operator-(const Unit_T other) const {
    if (this->IsPlusInfinity() || other.IsMinusInfinity()) {
      RTC_DCHECK(!this->IsMinusInfinity());
      RTC_DCHECK(!other.IsPlusInfinity());
      return this->PlusInfinity();
    } else if (this->IsMinusInfinity() || other.IsPlusInfinity()) {
      RTC_DCHECK(!this->IsPlusInfinity());
      RTC_DCHECK(!other.IsMinusInfinity());
      return this->MinusInfinity();
    }
    return UnitBase<Unit_T>::FromValue(this->ToValue() - other.ToValue());
  }
  Unit_T& operator+=(const Unit_T other) {
    *this = *this + other;
    return this->AsSubClassRef();
  }
  Unit_T& operator-=(const Unit_T other) {
    *this = *this - other;
    return this->AsSubClassRef();
  }
  constexpr double operator/(const Unit_T other) const {
    return UnitBase<Unit_T>::template ToValue<double>() /
           other.template ToValue<double>();
  }
  template <typename T>
  typename std::enable_if<std::is_arithmetic<T>::value, Unit_T>::type operator/(
      const T& scalar) const {
    return UnitBase<Unit_T>::FromValue(
        std::round(UnitBase<Unit_T>::template ToValue<int64_t>() / scalar));
  }
  Unit_T operator*(const double scalar) const {
    return UnitBase<Unit_T>::FromValue(std::round(this->ToValue() * scalar));
  }
  Unit_T operator*(const int64_t scalar) const {
    return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);
  }
  Unit_T operator*(const int32_t scalar) const {
    return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);
  }

 protected:
  using UnitBase<Unit_T>::UnitBase;
};

template <class Unit_T>
inline Unit_T operator*(const double scalar, const RelativeUnit<Unit_T> other) {
  return other * scalar;
}
template <class Unit_T>
inline Unit_T operator*(const int64_t scalar,
                        const RelativeUnit<Unit_T> other) {
  return other * scalar;
}
template <class Unit_T>
inline Unit_T operator*(const int32_t& scalar,
                        const RelativeUnit<Unit_T> other) {
  return other * scalar;
}

}  // namespace rtc_units_impl

}  // namespace webrtc

#endif  // RTC_BASE_UNITS_UNIT_BASE_H_
