/*
 *  Copyright (c) 2012 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.
 */

#include "webrtc/video_engine/call_stats.h"

#include <assert.h>

#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace.h"

namespace webrtc {

// A rtt report is considered valid for this long.
const int kRttTimeoutMs = 1500;
// Time interval for updating the observers.
const int kUpdateIntervalMs = 1000;

class RtcpObserver : public RtcpRttStats {
 public:
  explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
  virtual ~RtcpObserver() {}

  virtual void OnRttUpdate(uint32_t rtt) {
    owner_->OnRttUpdate(rtt);
  }

  virtual uint32_t LastProcessedRtt() const {
    return owner_->last_processed_rtt_ms();
  }

 private:
  CallStats* owner_;

  DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
};

CallStats::CallStats()
    : crit_(CriticalSectionWrapper::CreateCriticalSection()),
      rtcp_rtt_stats_(new RtcpObserver(this)),
      last_process_time_(TickTime::MillisecondTimestamp()),
      last_processed_rtt_ms_(0) {
}

CallStats::~CallStats() {
  assert(observers_.empty());
}

int32_t CallStats::TimeUntilNextProcess() {
  return last_process_time_ + kUpdateIntervalMs -
      TickTime::MillisecondTimestamp();
}

int32_t CallStats::Process() {
  CriticalSectionScoped cs(crit_.get());
  if (TickTime::MillisecondTimestamp() < last_process_time_ + kUpdateIntervalMs)
    return 0;

  // Remove invalid, as in too old, rtt values.
  int64_t time_now = TickTime::MillisecondTimestamp();
  while (!reports_.empty() && reports_.front().time + kRttTimeoutMs <
         time_now) {
    reports_.pop_front();
  }

  // Find the max stored RTT.
  uint32_t max_rtt = 0;
  for (std::list<RttTime>::const_iterator it = reports_.begin();
       it != reports_.end(); ++it) {
    if (it->rtt > max_rtt)
      max_rtt = it->rtt;
  }

  // If there is a valid rtt, update all observers.
  if (max_rtt > 0) {
    for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
         it != observers_.end(); ++it) {
      (*it)->OnRttUpdate(max_rtt);
    }
  }
  last_processed_rtt_ms_ = max_rtt;
  last_process_time_ = time_now;
  return 0;
}

uint32_t CallStats::last_processed_rtt_ms() const {
  CriticalSectionScoped cs(crit_.get());
  return last_processed_rtt_ms_;
}

RtcpRttStats* CallStats::rtcp_rtt_stats() const {
  return rtcp_rtt_stats_.get();
}

void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
  CriticalSectionScoped cs(crit_.get());
  for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
       it != observers_.end(); ++it) {
    if (*it == observer)
      return;
  }
  observers_.push_back(observer);
}

void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
  CriticalSectionScoped cs(crit_.get());
  for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
       it != observers_.end(); ++it) {
    if (*it == observer) {
      observers_.erase(it);
      return;
    }
  }
}

void CallStats::OnRttUpdate(uint32_t rtt) {
  CriticalSectionScoped cs(crit_.get());
  int64_t time_now = TickTime::MillisecondTimestamp();
  reports_.push_back(RttTime(rtt, time_now));
}

}  // namespace webrtc
