// Copyright (c) 2011 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 CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_
#define CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_

#include <stdint.h>

#include "base/time/time.h"
#include "content/common/content_export.h"

namespace content {

// SiteSpecificTimeDelta<T> is base::TimeDelta with a type tag. It it
// essentially base::TimeDelta, but SiteSpecificTimeDelta<T> is different from
// SiteSpecificTimeDelta<U> if T is different from U.
template <typename T>
class SiteSpecificTimeDelta final {
 public:
  SiteSpecificTimeDelta() = default;
  static SiteSpecificTimeDelta<T> FromTimeDelta(base::TimeDelta delta) {
    return SiteSpecificTimeDelta<T>(delta);
  }
  static SiteSpecificTimeDelta<T> FromMicroseconds(int64_t usec) {
    return SiteSpecificTimeDelta<T>(base::TimeDelta::FromMicroseconds(usec));
  }

  base::TimeDelta ToTimeDelta() const { return delta_; }
  bool operator==(const SiteSpecificTimeDelta<T> rhs) const {
    return delta_ == rhs.delta_;
  }
  bool operator<(const SiteSpecificTimeDelta<T> rhs) const {
    return delta_ < rhs.delta_;
  }
  bool operator<=(const SiteSpecificTimeDelta<T> rhs) const {
    return delta_ <= rhs.delta_;
  }

 private:
  explicit SiteSpecificTimeDelta(base::TimeDelta delta) : delta_(delta) {}

  base::TimeDelta delta_;
};

// For logging use only.
template <typename T>
std::ostream& operator<<(std::ostream& os, SiteSpecificTimeDelta<T> delta) {
  return os << delta.ToTimeDelta();
}

// SiteSpecificTimeTicks<T> is base::TimeTicks with a type tag. It is
// essentially base::TimeTicks, but SiteSpecificTimeTicks<T> is different from
// SiteSpecificTimeTicks<U> if T is different from U.
template <typename T>
class SiteSpecificTimeTicks final {
 public:
  SiteSpecificTimeTicks() = default;
  static SiteSpecificTimeTicks<T> FromTimeTicks(base::TimeTicks time_ticks) {
    return SiteSpecificTimeTicks<T>(time_ticks);
  }

  base::TimeTicks ToTimeTicks() const { return time_ticks_; }
  bool is_null() const { return time_ticks_.is_null(); }

  SiteSpecificTimeTicks<T> operator+(SiteSpecificTimeDelta<T> delta) const {
    return SiteSpecificTimeTicks<T>(time_ticks_ + delta.ToTimeDelta());
  }
  SiteSpecificTimeDelta<T> operator-(SiteSpecificTimeTicks<T> rhs) const {
    return SiteSpecificTimeDelta<T>::FromTimeDelta(time_ticks_ -
                                                   rhs.time_ticks_);
  }
  bool operator<(const SiteSpecificTimeTicks<T> rhs) const {
    return time_ticks_ < rhs.time_ticks_;
  }
  bool operator==(const SiteSpecificTimeTicks<T> rhs) const {
    return time_ticks_ == rhs.time_ticks_;
  }
  bool operator<=(const SiteSpecificTimeTicks<T> rhs) const {
    return time_ticks_ <= rhs.time_ticks_;
  }

 private:
  explicit SiteSpecificTimeTicks(base::TimeTicks time_ticks)
      : time_ticks_(time_ticks) {}

  base::TimeTicks time_ticks_;
};

// For logging use only.
template <typename T>
std::ostream& operator<<(std::ostream& os,
                         SiteSpecificTimeTicks<T> time_ticks) {
  return os << time_ticks.ToTimeTicks();
}

class SiteSpecificTimeLocalTag;
using LocalTimeTicks = SiteSpecificTimeTicks<SiteSpecificTimeLocalTag>;
using LocalTimeDelta = SiteSpecificTimeDelta<SiteSpecificTimeLocalTag>;

class SiteSpecificTimeRemoteTag;
using RemoteTimeTicks = SiteSpecificTimeTicks<SiteSpecificTimeRemoteTag>;
using RemoteTimeDelta = SiteSpecificTimeDelta<SiteSpecificTimeRemoteTag>;

// On Windows, TimeTicks are not always consistent between processes as
// indicated by |TimeTicks::IsConsistentAcrossProcesses()|. Often, the values on
// one process have a static offset relative to another. Occasionally, these
// offsets shift while running.
//
// To combat this, any TimeTicks values sent from the remote process to the
// local process must be tweaked in order to appear monotonic.
//
// In order to properly tweak ticks, we need 4 reference points:
//
// - |local_lower_bound|:  A known point, recorded on the local process, that
//                         occurs before any remote values that will be
//                         converted.
// - |remote_lower_bound|: The equivalent point on the remote process. This
//                         should be recorded immediately after
//                         |local_lower_bound|.
// - |local_upper_bound|:  A known point, recorded on the local process, that
//                         occurs after any remote values that will be
//                         converted.
// - |remote_upper_bound|: The equivalent point on the remote process. This
//                         should be recorded immediately before
//                         |local_upper_bound|.
//
// Once these bounds are determined, values within the remote process's range
// can be converted to the local process's range. The values are converted as
// follows:
//
// 1. If the remote's range exceeds the local's range, it is scaled to fit.
//    Any values converted will have the same scale factor applied.
//
// 2. The remote's range is shifted so that it is centered within the
//    local's range. Any values converted will be shifted the same amount.
class CONTENT_EXPORT InterProcessTimeTicksConverter {
 public:
  InterProcessTimeTicksConverter(LocalTimeTicks local_lower_bound,
                                 LocalTimeTicks local_upper_bound,
                                 RemoteTimeTicks remote_lower_bound,
                                 RemoteTimeTicks remote_upper_bound);

  // Returns the value within the local's bounds that correlates to
  // |remote_ms|.
  LocalTimeTicks ToLocalTimeTicks(RemoteTimeTicks remote_ms) const;

  // Returns the equivalent delta after applying remote-to-local scaling to
  // |remote_delta|.
  LocalTimeDelta ToLocalTimeDelta(RemoteTimeDelta remote_delta) const;

  // Returns the (remote time) - (local time) difference estimated by the
  // converter. This is the constant that is subtracted from remote TimeTicks to
  // get local TimeTicks when no scaling is applied.
  base::TimeDelta GetSkewForMetrics() const;

 private:
  // The local time which |remote_lower_bound_| is mapped to.
  LocalTimeTicks local_base_time_;
  LocalTimeDelta local_range_;

  double range_conversion_rate_;

  RemoteTimeTicks remote_lower_bound_;
  RemoteTimeTicks remote_upper_bound_;
};

}  // namespace content

#endif  // CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_
