/*
 *  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 sommonly useful operations. The undelying
// 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_
