/*
 *  Copyright (c) 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 MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
#include <stdint.h>
#include <limits>
#include <ostream>
#include "rtc_base/checks.h"

namespace webrtc {
namespace units_internal {
inline int64_t DivideAndRound(int64_t numerator, int64_t denominators) {
  if (numerator >= 0) {
    return (numerator + (denominators / 2)) / denominators;
  } else {
    return (numerator + (denominators / 2)) / denominators - 1;
  }
}
}  // namespace units_internal

// TimeDelta represents the difference between two timestamps. Connomly this can
// be a duration. However since two Timestamps are not guaranteed to have the
// same epoch (they might come from different computers, making exact
// synchronisation infeasible), the duration covered by a TimeDelta can be
// undefined. To simplify usage, it can be constructed and converted to
// different units, specifically seconds (s), milliseconds (ms) and
// microseconds (us).
class TimeDelta {
 public:
  static const TimeDelta kPlusInfinity;
  static const TimeDelta kMinusInfinity;
  static const TimeDelta kNotInitialized;
  static const TimeDelta kZero;
  TimeDelta() : TimeDelta(kNotInitialized) {}
  static TimeDelta Zero() { return kZero; }
  static TimeDelta Infinity() { return kPlusInfinity; }
  static TimeDelta seconds(int64_t seconds) { return TimeDelta::s(seconds); }
  static TimeDelta s(int64_t seconds) {
    return TimeDelta::us(seconds * 1000000);
  }
  static TimeDelta ms(int64_t milliseconds) {
    return TimeDelta::us(milliseconds * 1000);
  }
  static TimeDelta us(int64_t microseconds) {
    // Infinities only allowed via use of explicit constants.
    RTC_DCHECK(microseconds > std::numeric_limits<int64_t>::min());
    RTC_DCHECK(microseconds < std::numeric_limits<int64_t>::max());
    return TimeDelta(microseconds);
  }
  int64_t s() const { return units_internal::DivideAndRound(us(), 1000000); }
  int64_t ms() const { return units_internal::DivideAndRound(us(), 1000); }
  int64_t us() const {
    RTC_DCHECK(IsFinite());
    return microseconds_;
  }
  TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
  bool IsZero() const { return microseconds_ == 0; }
  bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
  bool IsInitialized() const {
    return microseconds_ != kNotInitialized.microseconds_;
  }
  bool IsInfinite() const {
    return *this == kPlusInfinity || *this == kMinusInfinity;
  }
  TimeDelta operator+(const TimeDelta& other) const {
    return TimeDelta::us(us() + other.us());
  }
  TimeDelta operator-(const TimeDelta& other) const {
    return TimeDelta::us(us() - other.us());
  }
  TimeDelta& operator-=(const TimeDelta& other) {
    microseconds_ -= other.us();
    return *this;
  }
  TimeDelta& operator+=(const TimeDelta& other) {
    microseconds_ += other.us();
    return *this;
  }
  TimeDelta operator*(double scalar) const;
  TimeDelta operator*(int64_t scalar) const {
    return TimeDelta::us(us() * scalar);
  }
  TimeDelta operator*(int32_t scalar) const {
    return TimeDelta::us(us() * scalar);
  }
  bool operator==(const TimeDelta& other) const {
    return microseconds_ == other.microseconds_;
  }
  bool operator!=(const TimeDelta& other) const {
    return microseconds_ != other.microseconds_;
  }
  bool operator<=(const TimeDelta& other) const {
    return microseconds_ <= other.microseconds_;
  }
  bool operator>=(const TimeDelta& other) const {
    return microseconds_ >= other.microseconds_;
  }
  bool operator>(const TimeDelta& other) const {
    return microseconds_ > other.microseconds_;
  }
  bool operator<(const TimeDelta& other) const {
    return microseconds_ < other.microseconds_;
  }

 private:
  explicit TimeDelta(int64_t us) : microseconds_(us) {}
  int64_t microseconds_;
};
inline TimeDelta operator*(const double& scalar, const TimeDelta& delta) {
  return delta * scalar;
}
inline TimeDelta operator*(const int64_t& scalar, const TimeDelta& delta) {
  return delta * scalar;
}
inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) {
  return delta * scalar;
}

// Timestamp represents the time that has passed since some unspecified epoch.
// The epoch is assumed to be before any represented timestamps, this means that
// negative values are not valid. The most notable feature is that the
// difference of two Timestamps results in a TimeDelta.
class Timestamp {
 public:
  static const Timestamp kPlusInfinity;
  static const Timestamp kNotInitialized;
  Timestamp() : Timestamp(kNotInitialized) {}
  static Timestamp Infinity() { return kPlusInfinity; }
  static Timestamp seconds(int64_t seconds) { return Timestamp::s(seconds); }
  static Timestamp s(int64_t seconds) {
    return Timestamp::us(seconds * 1000000);
  }
  static Timestamp ms(int64_t millis) { return Timestamp::us(millis * 1000); }
  static Timestamp us(int64_t micros) {
    RTC_DCHECK_GE(micros, 0);
    return Timestamp(micros);
  }
  int64_t s() const { return units_internal::DivideAndRound(us(), 1000000); }
  int64_t ms() const { return units_internal::DivideAndRound(us(), 1000); }
  int64_t us() const {
    RTC_DCHECK(IsFinite());
    return microseconds_;
  }
  bool IsInfinite() const {
    return microseconds_ == kPlusInfinity.microseconds_;
  }
  bool IsInitialized() const {
    return microseconds_ != kNotInitialized.microseconds_;
  }
  bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
  TimeDelta operator-(const Timestamp& other) const {
    return TimeDelta::us(us() - other.us());
  }
  Timestamp operator-(const TimeDelta& delta) const {
    return Timestamp::us(us() - delta.us());
  }
  Timestamp operator+(const TimeDelta& delta) const {
    return Timestamp::us(us() + delta.us());
  }
  Timestamp& operator-=(const TimeDelta& other) {
    microseconds_ -= other.us();
    return *this;
  }
  Timestamp& operator+=(const TimeDelta& other) {
    microseconds_ += other.us();
    return *this;
  }
  bool operator==(const Timestamp& other) const {
    return microseconds_ == other.microseconds_;
  }
  bool operator!=(const Timestamp& other) const {
    return microseconds_ != other.microseconds_;
  }
  bool operator<=(const Timestamp& other) const { return us() <= other.us(); }
  bool operator>=(const Timestamp& other) const { return us() >= other.us(); }
  bool operator>(const Timestamp& other) const { return us() > other.us(); }
  bool operator<(const Timestamp& other) const { return us() < other.us(); }

 private:
  explicit Timestamp(int64_t us) : microseconds_(us) {}
  int64_t microseconds_;
};

// DataSize is a class represeting a count of bytes. Note that while it can be
// initialized by a number of bits, it does not guarantee that the resolution is
// kept and the internal storage is in bytes. The number of bits will be
// truncated to fit.
class DataSize {
 public:
  static const DataSize kZero;
  static const DataSize kPlusInfinity;
  static const DataSize kNotInitialized;
  DataSize() : DataSize(kNotInitialized) {}
  static DataSize Zero() { return kZero; }
  static DataSize Infinity() { return kPlusInfinity; }
  static DataSize bytes(int64_t bytes) {
    RTC_DCHECK_GE(bytes, 0);
    return DataSize(bytes);
  }
  static DataSize bits(int64_t bits) {
    RTC_DCHECK_GE(bits, 0);
    return DataSize(bits / 8);
  }
  int64_t bytes() const {
    RTC_DCHECK(IsFinite());
    return bytes_;
  }
  int64_t kilobytes() const {
    return units_internal::DivideAndRound(bytes(), 1000);
  }
  int64_t bits() const { return bytes() * 8; }
  int64_t kilobits() const {
    return units_internal::DivideAndRound(bits(), 1000);
  }
  bool IsZero() const { return bytes_ == 0; }
  bool IsInfinite() const { return bytes_ == kPlusInfinity.bytes_; }
  bool IsInitialized() const { return bytes_ != kNotInitialized.bytes_; }
  bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
  DataSize operator-(const DataSize& other) const {
    return DataSize::bytes(bytes() - other.bytes());
  }
  DataSize operator+(const DataSize& other) const {
    return DataSize::bytes(bytes() + other.bytes());
  }
  DataSize operator*(double scalar) const;
  DataSize operator*(int64_t scalar) const {
    return DataSize::bytes(bytes() * scalar);
  }
  DataSize operator*(int32_t scalar) const {
    return DataSize::bytes(bytes() * scalar);
  }
  DataSize operator/(int64_t scalar) const {
    return DataSize::bytes(bytes() / scalar);
  }
  DataSize& operator-=(const DataSize& other) {
    bytes_ -= other.bytes();
    return *this;
  }
  DataSize& operator+=(const DataSize& other) {
    bytes_ += other.bytes();
    return *this;
  }
  bool operator==(const DataSize& other) const {
    return bytes_ == other.bytes_;
  }
  bool operator!=(const DataSize& other) const {
    return bytes_ != other.bytes_;
  }
  bool operator<=(const DataSize& other) const {
    return bytes_ <= other.bytes_;
  }
  bool operator>=(const DataSize& other) const {
    return bytes_ >= other.bytes_;
  }
  bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
  bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }

 private:
  explicit DataSize(int64_t bytes) : bytes_(bytes) {}
  int64_t bytes_;
};
inline DataSize operator*(const double& scalar, const DataSize& size) {
  return size * scalar;
}
inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
  return size * scalar;
}
inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
  return size * scalar;
}

// DataRate is a class that represents a given data rate. This can be used to
// represent bandwidth, encoding bitrate, etc. The internal storage is currently
// bits per second (bps) since this makes it easier to intepret the raw value
// when debugging. The promised precision, however is only that it will
// represent bytes per second accurately. Any implementation depending on bps
// resolution should document this by changing this comment.
class DataRate {
 public:
  static const DataRate kZero;
  static const DataRate kPlusInfinity;
  static const DataRate kNotInitialized;
  DataRate() : DataRate(kNotInitialized) {}
  static DataRate Zero() { return kZero; }
  static DataRate Infinity() { return kPlusInfinity; }
  static DataRate bytes_per_second(int64_t bytes_per_sec) {
    RTC_DCHECK_GE(bytes_per_sec, 0);
    return DataRate(bytes_per_sec * 8);
  }
  static DataRate bits_per_second(int64_t bits_per_sec) {
    RTC_DCHECK_GE(bits_per_sec, 0);
    return DataRate(bits_per_sec);
  }
  static DataRate bps(int64_t bits_per_sec) {
    return DataRate::bits_per_second(bits_per_sec);
  }
  static DataRate kbps(int64_t kilobits_per_sec) {
    return DataRate::bits_per_second(kilobits_per_sec * 1000);
  }
  int64_t bits_per_second() const {
    RTC_DCHECK(IsFinite());
    return bits_per_sec_;
  }
  int64_t bytes_per_second() const { return bits_per_second() / 8; }
  int64_t bps() const { return bits_per_second(); }
  int64_t bps_or(int64_t fallback) const {
    return IsFinite() ? bits_per_second() : fallback;
  }
  int64_t kbps() const { return units_internal::DivideAndRound(bps(), 1000); }
  bool IsZero() const { return bits_per_sec_ == 0; }
  bool IsInfinite() const {
    return bits_per_sec_ == kPlusInfinity.bits_per_sec_;
  }
  bool IsInitialized() const {
    return bits_per_sec_ != kNotInitialized.bits_per_sec_;
  }
  bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
  DataRate operator*(double scalar) const;
  DataRate operator*(int64_t scalar) const {
    return DataRate::bytes_per_second(bytes_per_second() * scalar);
  }
  DataRate operator*(int32_t scalar) const {
    return DataRate::bytes_per_second(bytes_per_second() * scalar);
  }
  bool operator==(const DataRate& other) const {
    return bits_per_sec_ == other.bits_per_sec_;
  }
  bool operator!=(const DataRate& other) const {
    return bits_per_sec_ != other.bits_per_sec_;
  }
  bool operator<=(const DataRate& other) const {
    return bits_per_sec_ <= other.bits_per_sec_;
  }
  bool operator>=(const DataRate& other) const {
    return bits_per_sec_ >= other.bits_per_sec_;
  }
  bool operator>(const DataRate& other) const {
    return bits_per_sec_ > other.bits_per_sec_;
  }
  bool operator<(const DataRate& other) const {
    return bits_per_sec_ < other.bits_per_sec_;
  }

 private:
  // Bits per second used internally to simplify debugging by making the value
  // more recognizable.
  explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {}
  int64_t bits_per_sec_;
};
inline DataRate operator*(const double& scalar, const DataRate& rate) {
  return rate * scalar;
}
inline DataRate operator*(const int64_t& scalar, const DataRate& rate) {
  return rate * scalar;
}
inline DataRate operator*(const int32_t& scalar, const DataRate& rate) {
  return rate * scalar;
}

DataRate operator/(const DataSize& size, const TimeDelta& duration);
TimeDelta operator/(const DataSize& size, const DataRate& rate);
DataSize operator*(const DataRate& rate, const TimeDelta& duration);
DataSize operator*(const TimeDelta& duration, const DataRate& rate);

::std::ostream& operator<<(::std::ostream& os, const DataRate& datarate);
::std::ostream& operator<<(::std::ostream& os, const DataSize& datasize);
::std::ostream& operator<<(::std::ostream& os, const Timestamp& timestamp);
::std::ostream& operator<<(::std::ostream& os, const TimeDelta& delta);

}  // namespace webrtc

#endif  // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
