// 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 function that return a Value representation of the parameters
  // associated with an event.  If called, it will be called synchonously,
  // so it need not have owning references.  May be called more than once, or
  // not at all.  May return NULL.
  typedef base::Callback<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_dependecy" 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 the capture mode for this NetLog. This is used to avoid computing
  // and saving expensive log entries.
  NetLogCaptureMode GetCaptureMode() 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, or has its log
  // capture mode changed.  Must have acquired |lock_| prior to calling.
  void UpdateCaptureMode();

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

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

  // The current capture mode. Note that the capture mode is stored as an
  // integer rather than a NetLogCaptureMode so that it can be easily
  // read/written without a lock using Atomic32.
  base::subtle::Atomic32 effective_capture_mode_int32_;

  // |lock_| must be acquired whenever reading or writing to this.
  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;

  NetLogCaptureMode GetCaptureMode() 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_
