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

#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
#define QUICHE_QUIC_CORE_QUIC_INTERVAL_H_

// An QuicInterval<T> is a data structure used to represent a contiguous,
// mutable range over an ordered type T. Supported operations include testing a
// value to see whether it is included in the QuicInterval, comparing two
// QuicIntervals, and performing their union, intersection, and difference. For
// the purposes of this library, an "ordered type" is any type that induces a
// total order on its values via its less-than operator (operator<()). Examples
// of such types are basic arithmetic types like int and double as well as class
// types like string.
//
// An QuicInterval<T> is represented using the usual C++ STL convention, namely
// as the half-open QuicInterval [min, max). A point p is considered to be
// contained in the QuicInterval iff p >= min && p < max. One consequence of
// this definition is that for any non-empty QuicInterval, min is contained in
// the QuicInterval but max is not. There is no canonical representation for the
// empty QuicInterval; rather, any QuicInterval where max <= min is regarded as
// empty. As a consequence, two empty QuicIntervals will still compare as equal
// despite possibly having different underlying min() or max() values. Also
// beware of the terminology used here: the library uses the terms "min" and
// "max" rather than "begin" and "end" as is conventional for the STL.
//
// T is required to be default- and copy-constructable, to have an assignment
// operator, and the full complement of comparison operators (<, <=, ==, !=, >=,
// >).  A difference operator (operator-()) is required if
// QuicInterval<T>::Length is used.
//
// QuicInterval supports operator==. Two QuicIntervals are considered equal if
// either they are both empty or if their corresponding min and max fields
// compare equal. QuicInterval also provides an operator<. Unfortunately,
// operator< is currently buggy because its behavior is inconsistent with
// operator==: two empty ranges with different representations may be regarded
// as equal by operator== but regarded as different by operator<. Bug 9240050
// has been created to address this.
//
//
// Examples:
//   QuicInterval<int> r1(0, 100);  // The QuicInterval [0, 100).
//   EXPECT_TRUE(r1.Contains(0));
//   EXPECT_TRUE(r1.Contains(50));
//   EXPECT_FALSE(r1.Contains(100));  // 100 is just outside the QuicInterval.
//
//   QuicInterval<int> r2(50, 150);  // The QuicInterval [50, 150).
//   EXPECT_TRUE(r1.Intersects(r2));
//   EXPECT_FALSE(r1.Contains(r2));
//   EXPECT_TRUE(r1.IntersectWith(r2));  // Mutates r1.
//   EXPECT_EQ(QuicInterval<int>(50, 100), r1);  // r1 is now [50, 100).
//
//   QuicInterval<int> r3(1000, 2000);  // The QuicInterval [1000, 2000).
//   EXPECT_TRUE(r1.IntersectWith(r3));  // Mutates r1.
//   EXPECT_TRUE(r1.Empty());  // Now r1 is empty.
//   EXPECT_FALSE(r1.Contains(r1.min()));  // e.g. doesn't contain its own min.

#include <stddef.h>
#include <algorithm>
#include <ostream>
#include <type_traits>
#include <utility>
#include <vector>

#include "quic/platform/api/quic_export.h"

namespace quic {

template <typename T>
class QUIC_NO_EXPORT QuicInterval {
 private:
  // Type trait for deriving the return type for QuicInterval::Length.  If
  // operator-() is not defined for T, then the return type is void.  This makes
  // the signature for Length compile so that the class can be used for such T,
  // but code that calls Length would still generate a compilation error.
  template <typename U>
  class QUIC_NO_EXPORT DiffTypeOrVoid {
   private:
    template <typename V>
    static auto f(const V* v) -> decltype(*v - *v);
    template <typename V>
    static void f(...);

   public:
    using type = typename std::decay<decltype(f<U>(nullptr))>::type;
  };

 public:
  // Construct an QuicInterval representing an empty QuicInterval.
  QuicInterval() : min_(), max_() {}

  // Construct an QuicInterval representing the QuicInterval [min, max). If min
  // < max, the constructed object will represent the non-empty QuicInterval
  // containing all values from min up to (but not including) max. On the other
  // hand, if min >= max, the constructed object will represent the empty
  // QuicInterval.
  QuicInterval(const T& min, const T& max) : min_(min), max_(max) {}

  template <typename U1,
            typename U2,
            typename = typename std::enable_if<
                std::is_convertible<U1, T>::value &&
                std::is_convertible<U2, T>::value>::type>
  QuicInterval(U1&& min, U2&& max)
      : min_(std::forward<U1>(min)), max_(std::forward<U2>(max)) {}

  const T& min() const { return min_; }
  const T& max() const { return max_; }
  void SetMin(const T& t) { min_ = t; }
  void SetMax(const T& t) { max_ = t; }

  void Set(const T& min, const T& max) {
    SetMin(min);
    SetMax(max);
  }

  void Clear() { *this = {}; }

  bool Empty() const { return min() >= max(); }

  // Returns the length of this QuicInterval. The value returned is zero if
  // Empty() is true; otherwise the value returned is max() - min().
  typename DiffTypeOrVoid<T>::type Length() const {
    return (Empty() ? min() : max()) - min();
  }

  // Returns true iff t >= min() && t < max().
  bool Contains(const T& t) const { return min() <= t && max() > t; }

  // Returns true iff *this and i are non-empty, and *this includes i. "*this
  // includes i" means that for all t, if i.Contains(t) then this->Contains(t).
  // Note the unintuitive consequence of this definition: this method always
  // returns false when i is the empty QuicInterval.
  bool Contains(const QuicInterval& i) const {
    return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max();
  }

  // Returns true iff there exists some point t for which this->Contains(t) &&
  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
  bool Intersects(const QuicInterval& i) const {
    return !Empty() && !i.Empty() && min() < i.max() && max() > i.min();
  }

  // Returns true iff there exists some point t for which this->Contains(t) &&
  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
  // Furthermore, if the intersection is non-empty and the out pointer is not
  // null, this method stores the calculated intersection in *out.
  bool Intersects(const QuicInterval& i, QuicInterval* out) const;

  // Sets *this to be the intersection of itself with i. Returns true iff
  // *this was modified.
  bool IntersectWith(const QuicInterval& i);

  // Returns true iff this and other have disjoint closures.  For nonempty
  // intervals, that means there is at least one point between this and other.
  // Roughly speaking that means the intervals don't intersect, and they are not
  // adjacent.   Empty intervals are always separated from any other interval.
  bool Separated(const QuicInterval& other) const {
    if (Empty() || other.Empty())
      return true;
    return other.max() < min() || max() < other.min();
  }

  // Calculates the smallest QuicInterval containing both *this i, and updates
  // *this to represent that QuicInterval, and returns true iff *this was
  // modified.
  bool SpanningUnion(const QuicInterval& i);

  // Determines the difference between two QuicIntervals by finding all points
  // that are contained in *this but not in i, coalesces those points into the
  // largest possible contiguous QuicIntervals, and appends those QuicIntervals
  // to the *difference vector. Intuitively this can be thought of as "erasing"
  // i from *this. This will either completely erase *this (leaving nothing
  // behind), partially erase some of *this from the left or right side (leaving
  // some residual behind), or erase a hole in the middle of *this (leaving
  // behind an QuicInterval on either side). Therefore, 0, 1, or 2 QuicIntervals
  // will be appended to *difference. The method returns true iff the
  // intersection of *this and i is non-empty. The caller owns the vector and
  // the QuicInterval* pointers inside it. The difference vector is required to
  // be non-null.
  bool Difference(const QuicInterval& i,
                  std::vector<QuicInterval*>* difference) const;

  // Determines the difference between two QuicIntervals as in
  // Difference(QuicInterval&, vector*), but stores the results directly in out
  // parameters rather than dynamically allocating an QuicInterval* and
  // appending it to a vector. If two results are generated, the one with the
  // smaller value of min() will be stored in *lo and the other in *hi.
  // Otherwise (if fewer than two results are generated), unused arguments will
  // be set to the empty QuicInterval (it is possible that *lo will be empty and
  // *hi non-empty). The method returns true iff the intersection of *this and i
  // is non-empty.
  bool Difference(const QuicInterval& i,
                  QuicInterval* lo,
                  QuicInterval* hi) const;

  friend bool operator==(const QuicInterval& a, const QuicInterval& b) {
    bool ae = a.Empty();
    bool be = b.Empty();
    if (ae && be)
      return true;  // All empties are equal.
    if (ae != be)
      return false;  // Empty cannot equal nonempty.
    return a.min() == b.min() && a.max() == b.max();
  }

  friend bool operator!=(const QuicInterval& a, const QuicInterval& b) {
    return !(a == b);
  }

  // Defines a comparator which can be used to induce an order on QuicIntervals,
  // so that, for example, they can be stored in an ordered container such as
  // std::set. The ordering is arbitrary, but does provide the guarantee that,
  // for non-empty QuicIntervals X and Y, if X contains Y, then X <= Y.
  // TODO(kosak): The current implementation of this comparator has a problem
  // because the ordering it induces is inconsistent with that of Equals(). In
  // particular, this comparator does not properly consider all empty
  // QuicIntervals equivalent. Bug 9240050 has been created to track this.
  friend bool operator<(const QuicInterval& a, const QuicInterval& b) {
    return a.min() < b.min() || (!(b.min() < a.min()) && b.max() < a.max());
  }

 private:
  T min_;  // Inclusive lower bound.
  T max_;  // Exclusive upper bound.
};

// Constructs an QuicInterval by deducing the types from the function arguments.
template <typename T>
QuicInterval<T> MakeQuicInterval(T&& lhs, T&& rhs) {
  return QuicInterval<T>(std::forward<T>(lhs), std::forward<T>(rhs));
}

// Note: ideally we'd use
//   decltype(out << "[" << i.min() << ", " << i.max() << ")")
// as return type of the function, but as of July 2017 this triggers g++
// "sorry, unimplemented: string literal in function template signature" error.
template <typename T>
auto operator<<(std::ostream& out, const QuicInterval<T>& i)
    -> decltype(out << i.min()) {
  return out << "[" << i.min() << ", " << i.max() << ")";
}

//==============================================================================
// Implementation details: Clients can stop reading here.

template <typename T>
bool QuicInterval<T>::Intersects(const QuicInterval& i,
                                 QuicInterval* out) const {
  if (!Intersects(i))
    return false;
  if (out != nullptr) {
    *out = QuicInterval(std::max(min(), i.min()), std::min(max(), i.max()));
  }
  return true;
}

template <typename T>
bool QuicInterval<T>::IntersectWith(const QuicInterval& i) {
  if (Empty())
    return false;
  bool modified = false;
  if (i.min() > min()) {
    SetMin(i.min());
    modified = true;
  }
  if (i.max() < max()) {
    SetMax(i.max());
    modified = true;
  }
  return modified;
}

template <typename T>
bool QuicInterval<T>::SpanningUnion(const QuicInterval& i) {
  if (i.Empty())
    return false;
  if (Empty()) {
    *this = i;
    return true;
  }
  bool modified = false;
  if (i.min() < min()) {
    SetMin(i.min());
    modified = true;
  }
  if (i.max() > max()) {
    SetMax(i.max());
    modified = true;
  }
  return modified;
}

template <typename T>
bool QuicInterval<T>::Difference(const QuicInterval& i,
                                 std::vector<QuicInterval*>* difference) const {
  if (Empty()) {
    // <empty> - <i> = <empty>
    return false;
  }
  if (i.Empty()) {
    // <this> - <empty> = <this>
    difference->push_back(new QuicInterval(*this));
    return false;
  }
  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
    //            [------ this ------)
    // [------ i ------)
    //                 [-- result ---)
    difference->push_back(new QuicInterval(i.max(), max()));
    return true;
  }
  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
    // [------ this ------)
    //            [------ i ------)
    // [- result -)
    difference->push_back(new QuicInterval(min(), i.min()));
    return true;
  }
  if (min() < i.min() && max() > i.max()) {
    // [------- this --------)
    //      [---- i ----)
    // [ R1 )           [ R2 )
    // There are two results: R1 and R2.
    difference->push_back(new QuicInterval(min(), i.min()));
    difference->push_back(new QuicInterval(i.max(), max()));
    return true;
  }
  if (min() >= i.min() && max() <= i.max()) {
    //   [--- this ---)
    // [------ i --------)
    // Intersection is <this>, so difference yields the empty QuicInterval.
    // Nothing is appended to *difference.
    return true;
  }
  // No intersection. Append <this>.
  difference->push_back(new QuicInterval(*this));
  return false;
}

template <typename T>
bool QuicInterval<T>::Difference(const QuicInterval& i,
                                 QuicInterval* lo,
                                 QuicInterval* hi) const {
  // Initialize *lo and *hi to empty
  *lo = {};
  *hi = {};
  if (Empty())
    return false;
  if (i.Empty()) {
    *lo = *this;
    return false;
  }
  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
    //            [------ this ------)
    // [------ i ------)
    //                 [-- result ---)
    *hi = QuicInterval(i.max(), max());
    return true;
  }
  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
    // [------ this ------)
    //            [------ i ------)
    // [- result -)
    *lo = QuicInterval(min(), i.min());
    return true;
  }
  if (min() < i.min() && max() > i.max()) {
    // [------- this --------)
    //      [---- i ----)
    // [ R1 )           [ R2 )
    // There are two results: R1 and R2.
    *lo = QuicInterval(min(), i.min());
    *hi = QuicInterval(i.max(), max());
    return true;
  }
  if (min() >= i.min() && max() <= i.max()) {
    //   [--- this ---)
    // [------ i --------)
    // Intersection is <this>, so difference yields the empty QuicInterval.
    return true;
  }
  *lo = *this;  // No intersection.
  return false;
}

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
