// Copyright 2012 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.
//
// A class that manages the registration of types for server-issued
// notifications.

#ifndef SYNC_NOTIFIER_REGISTRATION_MANAGER_H_
#define SYNC_NOTIFIER_REGISTRATION_MANAGER_H_

#include <map>

#include "base/basictypes.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
// For invalidation::InvalidationListener::RegistrationState.
#include "google/cacheinvalidation/include/invalidation-listener.h"
#include "google/cacheinvalidation/include/types.h"
#include "sync/base/sync_export.h"
#include "sync/notifier/invalidation_util.h"

namespace syncer {

using ::invalidation::InvalidationListener;

// Manages the details of registering types for invalidation.
// Implements exponential backoff for repeated registration attempts
// to the invalidation client.
//
// TODO(akalin): Consolidate exponential backoff code.  Other
// implementations include the syncer thread (both versions) and XMPP
// retries.  The most sophisticated one is URLRequestThrottler; making
// that generic should work for everyone.
class SYNC_EXPORT_PRIVATE RegistrationManager : public base::NonThreadSafe {
 public:
  // Constants for exponential backoff (used by tests).
  static const int kInitialRegistrationDelaySeconds;
  static const int kRegistrationDelayExponent;
  static const double kRegistrationDelayMaxJitter;
  static const int kMinRegistrationDelaySeconds;
  static const int kMaxRegistrationDelaySeconds;

  // Types used by testing functions.
  struct PendingRegistrationInfo {
    PendingRegistrationInfo();

    // Last time a registration request was actually sent.
    base::Time last_registration_request;
    // Time the registration was attempted.
    base::Time registration_attempt;
    // The calculated delay of the pending registration (which may be
    // negative).
    base::TimeDelta delay;
    // The delay of the timer, which should be max(delay, 0).
    base::TimeDelta actual_delay;
  };
  // Map of object IDs with pending registrations to info about the
  // pending registration.
  typedef std::map<invalidation::ObjectId,
                   PendingRegistrationInfo,
                   ObjectIdLessThan>
      PendingRegistrationMap;

  // Does not take ownership of |invalidation_client_|.
  explicit RegistrationManager(
      invalidation::InvalidationClient* invalidation_client);

  virtual ~RegistrationManager();

  // Registers all object IDs included in the given set (that are not
  // already disabled) and unregisters all other object IDs. The return value is
  // the set of IDs that was unregistered.
  ObjectIdSet UpdateRegisteredIds(const ObjectIdSet& ids);

  // Marks the registration for the |id| lost and re-registers
  // it (unless it's disabled).
  void MarkRegistrationLost(const invalidation::ObjectId& id);

  // Marks registrations lost for all enabled object IDs and re-registers them.
  void MarkAllRegistrationsLost();

  // Marks the registration for the |id| permanently lost and blocks any future
  // registration attempts.
  void DisableId(const invalidation::ObjectId& id);

  // Calculate exponential backoff.  |jitter| must be Uniform[-1.0, 1.0].
  static double CalculateBackoff(double retry_interval,
                                 double initial_retry_interval,
                                 double min_retry_interval,
                                 double max_retry_interval,
                                 double backoff_exponent,
                                 double jitter,
                                 double max_jitter);

  // The functions below should only be used in tests.

  // Gets all currently registered ids.
  ObjectIdSet GetRegisteredIdsForTest() const;

  // Gets all pending registrations and their next min delays.
  PendingRegistrationMap GetPendingRegistrationsForTest() const;

  // Run pending registrations immediately.
  void FirePendingRegistrationsForTest();

 protected:
  // Overrideable for testing purposes.
  virtual double GetJitter();

 private:
  struct RegistrationStatus {
    RegistrationStatus(const invalidation::ObjectId& id,
                       RegistrationManager* manager);
    ~RegistrationStatus();

    // Calls registration_manager->DoRegister(model_type). (needed by
    // |registration_timer|).  Should only be called if |enabled| is
    // true.
    void DoRegister();

    // Sets |enabled| to false and resets other variables.
    void Disable();

    // The object for which this is the status.
    const invalidation::ObjectId id;
    // The parent registration manager.
    RegistrationManager* const registration_manager;

    // Whether this data type should be registered.  Set to false if
    // we get a non-transient registration failure.
    bool enabled;
    // The current registration state.
    InvalidationListener::RegistrationState state;
    // When we last sent a registration request.
    base::Time last_registration_request;
    // When we last tried to register.
    base::Time last_registration_attempt;
    // The calculated delay of any pending registration (which may be
    // negative).
    base::TimeDelta delay;
    // The minimum time to wait until any next registration attempt.
    // Increased after each consecutive failure.
    base::TimeDelta next_delay;
    // The actual timer for registration.
    base::OneShotTimer<RegistrationStatus> registration_timer;

    DISALLOW_COPY_AND_ASSIGN(RegistrationStatus);
  };
  typedef std::map<invalidation::ObjectId,
                   RegistrationStatus*,
                   ObjectIdLessThan>
      RegistrationStatusMap;

  // Does nothing if the given id is disabled.  Otherwise, if
  // |is_retry| is not set, registers the given type immediately and
  // resets all backoff parameters.  If |is_retry| is set, registers
  // the given type at some point in the future and increases the
  // delay until the next retry.
  void TryRegisterId(const invalidation::ObjectId& id,
                     bool is_retry);

  // Registers the given id, which must be valid, immediately.
  // Updates |last_registration| in the appropriate
  // RegistrationStatus.  Should only be called by
  // RegistrationStatus::DoRegister().
  void DoRegisterId(const invalidation::ObjectId& id);

  // Unregisters the given object ID.
  void UnregisterId(const invalidation::ObjectId& id);

  // Gets all currently registered ids.
  ObjectIdSet GetRegisteredIds() const;

  // Returns true iff the given object ID is registered.
  bool IsIdRegistered(const invalidation::ObjectId& id) const;

  RegistrationStatusMap registration_statuses_;
  // Weak pointer.
  invalidation::InvalidationClient* invalidation_client_;

  DISALLOW_COPY_AND_ASSIGN(RegistrationManager);
};

}  // namespace syncer

#endif  // SYNC_NOTIFIER_REGISTRATION_MANAGER_H_
