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

#ifndef NET_LOG_NET_LOG_H_
#define NET_LOG_NET_LOG_H_

#include <string>

#include "build/build_config.h"

#include "base/atomicops.h"
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/log/net_log_capture_mode.h"

namespace base {
class DictionaryValue;
class Value;
}

namespace net {

// NetLog is the destination for log messages generated by the network stack.
// Each log message has a "source" field which identifies the specific entity
// that generated the message (for example, which URLRequest or which
// SpdySession).
//
// To avoid needing to pass in the "source ID" to the logging functions, NetLog
// is usually accessed through a BoundNetLog, which will always pass in a
// specific source ID.
//
// All methods are thread safe, with the exception that no NetLog or
// NetLog::ThreadSafeObserver functions may be called by an observer's
// OnAddEntry() method.  Doing so will result in a deadlock.
//
// For a broader introduction see the design document:
// https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
class NET_EXPORT NetLog {
 public:
  enum EventType {
#define EVENT_TYPE(label) TYPE_##label,
#include "net/log/net_log_event_type_list.h"
#undef EVENT_TYPE
    EVENT_COUNT
  };

  // The 'phase' of an event trace (whether it marks the beginning or end
  // of an event.).
  enum EventPhase {
    PHASE_NONE,
    PHASE_BEGIN,
    PHASE_END,
  };

  // The "source" identifies the entity that generated the log message.
  enum SourceType {
#define SOURCE_TYPE(label) SOURCE_##label,
#include "net/log/net_log_source_type_list.h"
#undef SOURCE_TYPE
    SOURCE_COUNT
  };

  // A callback that returns a Value representation of the parameters
  // associated with an event.  If called, it will be called synchronously,
  // so it need not have owning references.  May be called more than once, or
  // not at all.  May return NULL.
  typedef base::Callback<scoped_ptr<base::Value>(NetLogCaptureMode)>
      ParametersCallback;

  // Identifies the entity that generated this log. The |id| field should
  // uniquely identify the source, and is used by log observers to infer
  // message groupings. Can use NetLog::NextID() to create unique IDs.
  struct NET_EXPORT Source {
    static const uint32 kInvalidId;

    Source();
    Source(SourceType type, uint32 id);
    bool IsValid() const;

    // Adds the source to a DictionaryValue containing event parameters,
    // using the name "source_dependency".
    void AddToEventParameters(base::DictionaryValue* event_params) const;

    // Returns a callback that returns a dictionary with a single entry
    // named "source_dependency" that describes |this|.
    ParametersCallback ToEventParametersCallback() const;

    // Attempts to extract a Source from a set of event parameters.  Returns
    // true and writes the result to |source| on success.  Returns false and
    // makes |source| an invalid source on failure.
    // TODO(mmenke):  Long term, we want to remove this.
    static bool FromEventParameters(base::Value* event_params, Source* source);

    SourceType type;
    uint32 id;
  };

  struct NET_EXPORT EntryData {
    EntryData(EventType type,
              Source source,
              EventPhase phase,
              base::TimeTicks time,
              const ParametersCallback* parameters_callback);
    ~EntryData();

    const EventType type;
    const Source source;
    const EventPhase phase;
    const base::TimeTicks time;
    const ParametersCallback* const parameters_callback;
  };

  // An Entry pre-binds EntryData to a capture mode, so observers will observe
  // the output of ToValue() and ParametersToValue() at their log capture mode
  // rather than the current maximum.
  class NET_EXPORT Entry {
   public:
    Entry(const EntryData* data, NetLogCaptureMode capture_mode);
    ~Entry();

    EventType type() const { return data_->type; }
    Source source() const { return data_->source; }
    EventPhase phase() const { return data_->phase; }

    // Serializes the specified event to a Value.  The Value also includes the
    // current time.  Caller takes ownership of returned Value.  Takes in a time
    // to allow back-dating entries.
    base::Value* ToValue() const;

    // Returns the parameters as a Value.  Returns NULL if there are no
    // parameters.  Caller takes ownership of returned Value.
    base::Value* ParametersToValue() const;

   private:
    const EntryData* const data_;

    // Log capture mode when the event occurred.
    const NetLogCaptureMode capture_mode_;

    // It is not safe to copy this class, since |parameters_callback_| may
    // include pointers that become stale immediately after the event is added,
    // even if the code were modified to keep its own copy of the callback.
    DISALLOW_COPY_AND_ASSIGN(Entry);
  };

  // An observer, that must ensure its own thread safety, for events
  // being added to a NetLog.
  class NET_EXPORT ThreadSafeObserver {
   public:
    // Constructs an observer that wants to see network events, with
    // the specified minimum event granularity.  A ThreadSafeObserver can only
    // observe a single NetLog at a time.
    //
    // Observers will be called on the same thread an entry is added on,
    // and are responsible for ensuring their own thread safety.
    //
    // Observers must stop watching a NetLog before either the Observer or the
    // NetLog is destroyed.
    ThreadSafeObserver();

    // Returns the capture mode for events this observer wants to
    // receive.  Must not be called when not watching a NetLog.
    NetLogCaptureMode capture_mode() const;

    // Returns the NetLog we are currently watching, if any.  Returns NULL
    // otherwise.
    NetLog* net_log() const;

    // This method will be called on the thread that the event occurs on.  It
    // is the responsibility of the observer to handle it in a thread safe
    // manner.
    //
    // It is illegal for an Observer to call any NetLog or
    // NetLog::Observer functions in response to a call to OnAddEntry.
    virtual void OnAddEntry(const Entry& entry) = 0;

   protected:
    virtual ~ThreadSafeObserver();

   private:
    friend class NetLog;

    void OnAddEntryData(const EntryData& entry_data);

    // Both of these values are only modified by the NetLog.
    NetLogCaptureMode capture_mode_;
    NetLog* net_log_;

    DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
  };

  NetLog();
  virtual ~NetLog();

  // Emits a global event to the log stream, with its own unique source ID.
  void AddGlobalEntry(EventType type);
  void AddGlobalEntry(EventType type,
                      const NetLog::ParametersCallback& parameters_callback);

  // Returns a unique ID which can be used as a source ID.  All returned IDs
  // will be unique and greater than 0.
  uint32 NextID();

  // Returns true if there are any observers attached to the NetLog. This can be
  // used as an optimization to avoid emitting log entries when there is no
  // chance that the data will be consumed.
  bool IsCapturing() const;

  // Adds an observer and sets its log capture mode.  The observer must not be
  // watching any NetLog, including this one, when this is called.
  //
  // NetLog implementations must call NetLog::OnAddObserver to update the
  // observer's internal state.
  //
  // DEPRECATED: The ability to watch the netlog stream is being phased out
  // (crbug.com/472693) as it can be misused in production code. Please consult
  // with a net/log OWNER before introducing a new dependency on this.
  void DeprecatedAddObserver(ThreadSafeObserver* observer,
                             NetLogCaptureMode capture_mode);

  // Sets the log capture mode of |observer| to |capture_mode|.  |observer| must
  // be watching |this|.  NetLog implementations must call
  // NetLog::OnSetObserverCaptureMode to update the observer's internal state.
  void SetObserverCaptureMode(ThreadSafeObserver* observer,
                              NetLogCaptureMode capture_mode);

  // Removes an observer.  NetLog implementations must call
  // NetLog::OnAddObserver to update the observer's internal state.
  //
  // For thread safety reasons, it is recommended that this not be called in
  // an object's destructor.
  //
  // DEPRECATED: The ability to watch the netlog stream is being phased out
  // (crbug.com/472693) as it can be misused in production code. Please consult
  // with a net/log OWNER before introducing a new dependency on this.
  void DeprecatedRemoveObserver(ThreadSafeObserver* observer);

  // Converts a time to the string format that the NetLog uses to represent
  // times.  Strings are used since integers may overflow.
  static std::string TickCountToString(const base::TimeTicks& time);

  // Returns a C-String symbolic name for |event_type|.
  static const char* EventTypeToString(EventType event_type);

  // Returns a dictionary that maps event type symbolic names to their enum
  // values.  Caller takes ownership of the returned Value.
  static base::Value* GetEventTypesAsValue();

  // Returns a C-String symbolic name for |source_type|.
  static const char* SourceTypeToString(SourceType source_type);

  // Returns a dictionary that maps source type symbolic names to their enum
  // values.  Caller takes ownership of the returned Value.
  static base::Value* GetSourceTypesAsValue();

  // Returns a C-String symbolic name for |event_phase|.
  static const char* EventPhaseToString(EventPhase event_phase);

  // Creates a ParametersCallback that encapsulates a single bool.
  // Warning: |name| must remain valid for the life of the callback.
  static ParametersCallback BoolCallback(const char* name, bool value);

  // Warning: |name| must remain valid for the life of the callback.
  // TODO(mmenke):  Rename this to be consistent with Int64Callback.
  static ParametersCallback IntegerCallback(const char* name, int value);

  // Creates a ParametersCallback that encapsulates a single int64.  The
  // callback will return the value as a StringValue, since IntegerValues
  // only support 32-bit values.
  // Warning: |name| must remain valid for the life of the callback.
  static ParametersCallback Int64Callback(const char* name, int64 value);

  // Creates a ParametersCallback that encapsulates a single UTF8 string.  Takes
  // |value| as a pointer to avoid copying, and emphasize it must be valid for
  // the life of the callback.  |value| may not be NULL.
  // Warning: |name| and |value| must remain valid for the life of the callback.
  static ParametersCallback StringCallback(const char* name,
                                           const std::string* value);

  // Same as above, but takes in a UTF16 string.
  static ParametersCallback StringCallback(const char* name,
                                           const base::string16* value);

 private:
  friend class BoundNetLog;

  void AddEntry(EventType type,
                const Source& source,
                EventPhase phase,
                const NetLog::ParametersCallback* parameters_callback);

  // Called whenever an observer is added or removed, to update
  // |has_observers_|. Must have acquired |lock_| prior to calling.
  void UpdateIsCapturing();

  // |lock_| protects access to |observers_|.
  base::Lock lock_;

  // Last assigned source ID.  Incremented to get the next one.
  base::subtle::Atomic32 last_id_;

  // |is_capturing_| will be 0 when there are no observers watching the NetLog,
  // 1 otherwise. Note that this is stored as an Atomic32 rather than a boolean
  // so it can be accessed without needing a lock.
  base::subtle::Atomic32 is_capturing_;

  // |lock_| must be acquired whenever reading or writing to this.
  base::ObserverList<ThreadSafeObserver, true> observers_;

  DISALLOW_COPY_AND_ASSIGN(NetLog);
};

// Helper that binds a Source to a NetLog, and exposes convenience methods to
// output log messages without needing to pass in the source.
class NET_EXPORT BoundNetLog {
 public:
  BoundNetLog() : net_log_(NULL) {}
  ~BoundNetLog();

  // Add a log entry to the NetLog for the bound source.
  void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const;
  void AddEntry(NetLog::EventType type,
                NetLog::EventPhase phase,
                const NetLog::ParametersCallback& get_parameters) const;

  // Convenience methods that call AddEntry with a fixed "capture phase"
  // (begin, end, or none).
  void BeginEvent(NetLog::EventType type) const;
  void BeginEvent(NetLog::EventType type,
                  const NetLog::ParametersCallback& get_parameters) const;

  void EndEvent(NetLog::EventType type) const;
  void EndEvent(NetLog::EventType type,
                const NetLog::ParametersCallback& get_parameters) const;

  void AddEvent(NetLog::EventType type) const;
  void AddEvent(NetLog::EventType type,
                const NetLog::ParametersCallback& get_parameters) const;

  // Just like AddEvent, except |net_error| is a net error code.  A parameter
  // called "net_error" with the indicated value will be recorded for the event.
  // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
  // error.
  void AddEventWithNetErrorCode(NetLog::EventType event_type,
                                int net_error) const;

  // Just like EndEvent, except |net_error| is a net error code.  If it's
  // negative, a parameter called "net_error" with a value of |net_error| is
  // associated with the event.  Otherwise, the end event has no parameters.
  // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
  void EndEventWithNetErrorCode(NetLog::EventType event_type,
                                int net_error) const;

  // Logs a byte transfer event to the NetLog.  Determines whether to log the
  // received bytes or not based on the current logging level.
  void AddByteTransferEvent(NetLog::EventType event_type,
                            int byte_count,
                            const char* bytes) const;

  bool IsCapturing() const;

  // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
  // of creating a unique source ID, and handles the case of NULL net_log.
  static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);

  const NetLog::Source& source() const { return source_; }
  NetLog* net_log() const { return net_log_; }

 private:
  // TODO(eroman): Temporary until crbug.com/467797 is solved.
  enum Liveness {
    ALIVE = 0xCA11AB13,
    DEAD = 0xDEADBEEF,
  };

  BoundNetLog(const NetLog::Source& source, NetLog* net_log)
      : source_(source), net_log_(net_log) {}

  // TODO(eroman): Temporary until crbug.com/467797 is solved.
  void CrashIfInvalid() const;

  NetLog::Source source_;
  NetLog* net_log_;

  // TODO(eroman): Temporary until crbug.com/467797 is solved.
  Liveness liveness_ = ALIVE;
};

}  // namespace net

#endif  // NET_LOG_NET_LOG_H_
