/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "ndn-limits-rate.hpp"

#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/random-variable.h"
#include "ns3/ndn-face.hpp"
#include "ns3/node.h"

NS_LOG_COMPONENT_DEFINE("ndn.Limits.Rate");

namespace ns3 {
namespace ndn {

NS_OBJECT_ENSURE_REGISTERED(LimitsRate);

TypeId
LimitsRate::GetTypeId()
{
  static TypeId tid =
    TypeId("ns3::ndn::Limits::Rate")
      .SetGroupName("Ndn")
      .SetParent<Limits>()
      .AddConstructor<LimitsRate>()

      .AddAttribute("RandomizeLeak", "Randomize start time for token bucket leakage. May be "
                                     "helpful to prevent leak synchronizations",
                    TimeValue(Seconds(0.001)),
                    MakeTimeAccessor(&LimitsRate::m_leakRandomizationInteral), MakeTimeChecker())

    ;
  return tid;
}

void
LimitsRate::NotifyNewAggregate()
{
  super::NotifyNewAggregate();

  if (!m_isLeakScheduled) {
    if (GetObject<Face>() != 0) {
      NS_ASSERT_MSG(GetObject<Face>()->GetNode() != 0, "Node object should exist on the face");

      m_isLeakScheduled = true;

      if (!m_leakRandomizationInteral.IsZero()) {
        UniformVariable r(0.0, m_leakRandomizationInteral.ToDouble(Time::S));
        Simulator::ScheduleWithContext(GetObject<Face>()->GetNode()->GetId(), Seconds(r.GetValue()),
                                       &LimitsRate::LeakBucket, this, 0.0);
      }
      else {
        Simulator::ScheduleWithContext(GetObject<Face>()->GetNode()->GetId(), Seconds(0),
                                       &LimitsRate::LeakBucket, this, 0.0);
      }
    }
  }
}

void
LimitsRate::SetLimits(double rate, double delay)
{
  super::SetLimits(rate, delay);

  // maximum allowed burst
  m_bucketMax = GetMaxRate() * GetMaxDelay();

  // amount of packets allowed every second (leak rate)
  m_bucketLeak = GetMaxRate();
}

void
LimitsRate::UpdateCurrentLimit(double limit)
{
  NS_ASSERT_MSG(limit >= 0.0, "Limit should be greater or equal to zero");

  m_bucketLeak = std::min(limit, GetMaxRate());
  m_bucketMax = m_bucketLeak * GetMaxDelay();
}

bool
LimitsRate::IsBelowLimit()
{
  if (!IsEnabled())
    return true;

  return (m_bucketMax - m_bucket >= 1.0);
}

void
LimitsRate::BorrowLimit()
{
  if (!IsEnabled())
    return;

  NS_ASSERT_MSG(m_bucketMax - m_bucket >= 1.0,
                "Should not be possible, unless we IsBelowLimit was not checked correctly");
  m_bucket += 1;
}

void
LimitsRate::ReturnLimit()
{
  // do nothing
}

void
LimitsRate::LeakBucket(double interval)
{
  const double leak = m_bucketLeak * interval;

#ifdef NS3_LOG_ENABLE
  if (m_bucket > 1) {
    NS_LOG_DEBUG("Leak from " << m_bucket << " to " << std::max(0.0, m_bucket - leak));
  }
#endif

  double bucketOld = m_bucket;

  m_bucket = std::max(0.0, m_bucket - leak);

  // calculate interval so next time we will leak by 1.001, unless such interval would be more than
  // 1 second
  double newInterval = 1.0;
  if (m_bucketLeak > 1.0) {
    newInterval = 1.001 / m_bucketLeak;
  }

  if (m_bucketMax - bucketOld < 1.0
      && m_bucketMax - m_bucket >= 1.0) // limit number of times this stuff is called
  {
    this->FireAvailableSlotCallback();
  }

  Simulator::Schedule(Seconds(newInterval), &LimitsRate::LeakBucket, this, newInterval);
}

} // namespace ndn
} // namespace ns3
