/*
 *  Copyright (c) 2016 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 WEBRTC_MODULES_VIDEO_CODING_SEQUENCE_NUMBER_UTIL_H_
#define WEBRTC_MODULES_VIDEO_CODING_SEQUENCE_NUMBER_UTIL_H_

#include <limits>
#include <type_traits>

#include "webrtc/api/optional.h"
#include "webrtc/rtc_base/mod_ops.h"
#include "webrtc/rtc_base/safe_compare.h"

namespace webrtc {

// Test if the sequence number |a| is ahead or at sequence number |b|.
//
// If |M| is an even number and the two sequence numbers are at max distance
// from each other, then the sequence number with the highest value is
// considered to be ahead.
template <typename T, T M>
inline typename std::enable_if<(M > 0), bool>::type AheadOrAt(T a, T b) {
  static_assert(std::is_unsigned<T>::value,
                "Type must be an unsigned integer.");
  const T maxDist = M / 2;
  if (!(M & 1) && MinDiff<T, M>(a, b) == maxDist)
    return b < a;
  return ForwardDiff<T, M>(b, a) <= maxDist;
}

template <typename T, T M>
inline typename std::enable_if<(M == 0), bool>::type AheadOrAt(T a, T b) {
  static_assert(std::is_unsigned<T>::value,
                "Type must be an unsigned integer.");
  const T maxDist = std::numeric_limits<T>::max() / 2 + T(1);
  if (a - b == maxDist)
    return b < a;
  return ForwardDiff(b, a) < maxDist;
}

template <typename T>
inline bool AheadOrAt(T a, T b) {
  return AheadOrAt<T, 0>(a, b);
}

// Test if the sequence number |a| is ahead of sequence number |b|.
//
// If |M| is an even number and the two sequence numbers are at max distance
// from each other, then the sequence number with the highest value is
// considered to be ahead.
template <typename T, T M = 0>
inline bool AheadOf(T a, T b) {
  static_assert(std::is_unsigned<T>::value,
                "Type must be an unsigned integer.");
  return a != b && AheadOrAt<T, M>(a, b);
}

// Comparator used to compare sequence numbers in a continuous fashion.
//
// WARNING! If used to sort sequence numbers of length M then the interval
//          covered by the sequence numbers may not be larger than floor(M/2).
template <typename T, T M = 0>
struct AscendingSeqNumComp {
  bool operator()(T a, T b) const { return AheadOf<T, M>(a, b); }
};

// Comparator used to compare sequence numbers in a continuous fashion.
//
// WARNING! If used to sort sequence numbers of length M then the interval
//          covered by the sequence numbers may not be larger than floor(M/2).
template <typename T, T M = 0>
struct DescendingSeqNumComp {
  bool operator()(T a, T b) const { return AheadOf<T, M>(b, a); }
};

// A sequencer number unwrapper where the start value of the unwrapped sequence
// can be set. The unwrapped value is not allowed to wrap.
template <typename T, T M = 0>
class SeqNumUnwrapper {
  // Use '<' instead of rtc::SafeLt to avoid crbug.com/753488
  static_assert(
      std::is_unsigned<T>::value &&
          std::numeric_limits<T>::max() < std::numeric_limits<uint64_t>::max(),
      "Type unwrapped must be an unsigned integer smaller than uint64_t.");

 public:
  // We want a value that is close to 2^63 for two reasons. Firstly, we
  // can unwrap wrapping numbers in either direction, and secondly, we avoid
  // causing a crash on bad input. We also want the default value to be somewhat
  // human readable, a power of 10 for example.
  static constexpr uint64_t kDefaultStartValue = 10000000000000000000UL;

  SeqNumUnwrapper() : last_unwrapped_(kDefaultStartValue) {}
  explicit SeqNumUnwrapper(uint64_t start_at) : last_unwrapped_(start_at) {}

  uint64_t Unwrap(T value) {
    if (!last_value_)
      last_value_.emplace(value);

    uint64_t unwrapped = 0;
    if (AheadOrAt<T, M>(value, *last_value_)) {
      unwrapped = last_unwrapped_ + ForwardDiff<T, M>(*last_value_, value);
      RTC_CHECK_GE(unwrapped, last_unwrapped_);
    } else {
      unwrapped = last_unwrapped_ - ReverseDiff<T, M>(*last_value_, value);
      RTC_CHECK_LT(unwrapped, last_unwrapped_);
    }

    *last_value_ = value;
    last_unwrapped_ = unwrapped;
    return last_unwrapped_;
  }

 private:
  uint64_t last_unwrapped_;
  rtc::Optional<T> last_value_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_VIDEO_CODING_SEQUENCE_NUMBER_UTIL_H_
