/*
 * libjingle
 * Copyright 2004--2006, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _RATELIMITMANAGER_H_
#define _RATELIMITMANAGER_H_

#include "talk/base/timeutils.h"
#include "talk/base/taskrunner.h"
#include <map>

namespace buzz {

/////////////////////////////////////////////////////////////////////
//
// RATELIMITMANAGER
//
/////////////////////////////////////////////////////////////////////
//
// RateLimitManager imposes client-side rate limiting for xmpp tasks and
// other events.  It ensures that no more than i events with a given name 
// can occur within k seconds. 
//
// A buffer tracks the previous max_count events.  Before an event is allowed
// to occur, it can check its rate limit with a call to VerifyRateLimit.  
// VerifyRateLimit will look up the i-th to last event and if more than
// k seconds have passed since then, it will return true and update the 
// appropriate rate limits.  Else, it will return false. 
//
/////////////////////////////////////////////////////////////////////

class RateLimitManager {
 public:

  RateLimitManager() { };
  ~RateLimitManager() { 
    for (RateLimitMap::iterator it = rate_limits_.begin();
         it != rate_limits_.end(); ++it) {
      delete it->second;
    }
  };

  // Checks if the event is under the defined rate limit and updates the
  // rate limit if so.  Returns true if it's under the rate limit.
  bool VerifyRateLimit(const std::string event_name, int max_count, 
                       int per_x_seconds);

  // Checks if the event is under the defined rate limit and updates the
  // rate limit if so *or* if always_update = true.  
  bool VerifyRateLimit(const std::string event_name, int max_count, 
                       int per_x_seconds, bool always_update);

 private:
  class RateLimit {
   public:
    RateLimit(int max, int per_x_secs) : counter_(0), max_count_(max),
                                         per_x_seconds_(per_x_secs) {
      event_times_ = new uint32[max_count_];                                                 
      for (int i = 0; i < max_count_; i++) {
        event_times_[i] = 0;
      }
    }

    ~RateLimit() {
      if (event_times_) {
        delete[] event_times_;
      }
    }

    // True iff the current time >= to the next song allowed time
    bool IsWithinRateLimit() {
      return (talk_base::TimeSince(NextTimeAllowedForCounter()) >= 0);
    }
    
    // Updates time and counter for rate limit
    void UpdateRateLimit() {
      event_times_[counter_] = talk_base::Time();
      counter_ = (counter_ + 1) % max_count_;
    }

   private:

    // The time at which the i-th (where i = max_count) event occured
    uint32 PreviousTimeAtCounter() {
      return event_times_[counter_];
    }

    // The time that the next event is allowed to occur
    uint32 NextTimeAllowedForCounter() {
      return PreviousTimeAtCounter() + per_x_seconds_ * talk_base::kSecToMsec;
    }

    int counter_; // count modulo max_count of the current event
    int max_count_; // max number of events that can occur within per_x_seconds
    int per_x_seconds_; // interval size for rate limit
    uint32* event_times_; // buffer of previous max_count event
  };

  typedef std::map<const std::string, RateLimit*> RateLimitMap;

  // Maps from event name to its rate limit
  RateLimitMap rate_limits_;

  // Returns rate limit for event with specified name
  RateLimit* GetRateLimit(const std::string event_name);

  // True iff the current time >= to the next song allowed time
  bool IsWithinRateLimit(const std::string event_name);

  // Updates time and counter for rate limit
  void UpdateRateLimit(const std::string event_name, int max_count, 
                       int per_x_seconds); 

};

}

#endif //_RATELIMITMANAGER_H_
