// Copyright 2014 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.

#include <algorithm>
#include <utility>

#include "base/logging.h"
#include "base/time/tick_clock.h"
#include "media/cast/logging/receiver_time_offset_estimator_impl.h"

namespace media {
namespace cast {

namespace {

// Bitwise merging of values to produce an ordered key for entries in the
// BoundCalculator::events_ map.
uint64_t MakeEventKey(RtpTimeTicks rtp, uint16_t packet_id, bool audio) {
  return (static_cast<uint64_t>(rtp.lower_32_bits()) << 32) |
         (static_cast<uint64_t>(packet_id) << 1) |
         (audio ? UINT64_C(1) : UINT64_C(0));
}

}  // namespace

ReceiverTimeOffsetEstimatorImpl::BoundCalculator::BoundCalculator()
    : has_bound_(false) {}
ReceiverTimeOffsetEstimatorImpl::BoundCalculator::~BoundCalculator() {}

void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetSent(
    RtpTimeTicks rtp,
    uint16_t packet_id,
    bool audio,
    base::TimeTicks t) {
  const uint64_t key = MakeEventKey(rtp, packet_id, audio);
  events_[key].first = t;
  CheckUpdate(key);
}

void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::SetReceived(
    RtpTimeTicks rtp,
    uint16_t packet_id,
    bool audio,
    base::TimeTicks t) {
  const uint64_t key = MakeEventKey(rtp, packet_id, audio);
  events_[key].second = t;
  CheckUpdate(key);
}

void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::UpdateBound(
    base::TimeTicks sent, base::TimeTicks received) {
    base::TimeDelta delta = received - sent;
    if (has_bound_) {
      if (delta < bound_) {
        bound_ = delta;
      } else {
        bound_ += (delta - bound_) / kClockDriftSpeed;
      }
    } else {
      bound_ = delta;
    }
    has_bound_ = true;
  }

  void ReceiverTimeOffsetEstimatorImpl::BoundCalculator::CheckUpdate(
      uint64_t key) {
  const TimeTickPair& ticks = events_[key];
  if (!ticks.first.is_null() && !ticks.second.is_null()) {
    UpdateBound(ticks.first, ticks.second);
    events_.erase(key);
    return;
  }

  if (events_.size() > kMaxEventTimesMapSize) {
    EventMap::iterator i = ModMapOldest(&events_);
    if (i != events_.end()) {
      events_.erase(i);
    }
  }
}

ReceiverTimeOffsetEstimatorImpl::ReceiverTimeOffsetEstimatorImpl() {
}

ReceiverTimeOffsetEstimatorImpl::~ReceiverTimeOffsetEstimatorImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
}


void ReceiverTimeOffsetEstimatorImpl::OnReceiveFrameEvent(
    const FrameEvent& frame_event) {
  DCHECK(thread_checker_.CalledOnValidThread());
  switch (frame_event.type) {
    case FRAME_ACK_SENT:
      lower_bound_.SetSent(frame_event.rtp_timestamp,
                           0,
                           frame_event.media_type == AUDIO_EVENT,
                           frame_event.timestamp);
      break;
    case FRAME_ACK_RECEIVED:
      lower_bound_.SetReceived(frame_event.rtp_timestamp,
                               0,
                               frame_event.media_type == AUDIO_EVENT,
                               frame_event.timestamp);
      break;
    default:
      // Ignored
      break;
  }
}

bool ReceiverTimeOffsetEstimatorImpl::GetReceiverOffsetBounds(
    base::TimeDelta* lower_bound,
    base::TimeDelta* upper_bound) {
  if (!lower_bound_.has_bound() || !upper_bound_.has_bound())
    return false;

  *lower_bound = -lower_bound_.bound();
  *upper_bound = upper_bound_.bound();

  // Sanitize the output, we don't want the upper bound to be
  // lower than the lower bound, make them the same.
  if (upper_bound < lower_bound) {
    lower_bound += (lower_bound - upper_bound) / 2;
    upper_bound = lower_bound;
  }
  return true;
}

void ReceiverTimeOffsetEstimatorImpl::OnReceivePacketEvent(
    const PacketEvent& packet_event) {
  DCHECK(thread_checker_.CalledOnValidThread());
  switch (packet_event.type) {
    case PACKET_SENT_TO_NETWORK:
      upper_bound_.SetSent(packet_event.rtp_timestamp,
                           packet_event.packet_id,
                           packet_event.media_type == AUDIO_EVENT,
                           packet_event.timestamp);
      break;
    case PACKET_RECEIVED:
      upper_bound_.SetReceived(packet_event.rtp_timestamp,
                               packet_event.packet_id,
                               packet_event.media_type == AUDIO_EVENT,
                               packet_event.timestamp);
      break;
    default:
      // Ignored
      break;
  }
}


}  // namespace cast
}  // namespace media
