// 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 MEDIA_BASE_MEDIA_LOG_H_
#define MEDIA_BASE_MEDIA_LOG_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <sstream>
#include <string>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/thread_annotations.h"
#include "media/base/buffering_state.h"
#include "media/base/media_export.h"
#include "media/base/media_log_event.h"
#include "media/base/pipeline_impl.h"
#include "media/base/pipeline_status.h"
#include "url/gurl.h"

namespace media {

// Interface for media components to log to chrome://media-internals log.
//
// To provide a logging implementation, derive from MediaLog instead.
//
// Implementations only need to implement AddEventLocked(), which must be thread
// safe in the sense that it may be called from multiple threads, though it will
// not be called concurrently.  See below for more details.
//
// Implementations should also call InvalidateLog during destruction, to signal
// to any child logs that the underlying log is no longer available.
class MEDIA_EXPORT MediaLog {
 public:
  enum MediaLogLevel {
    // Fatal error, e.g. cause of playback failure. Since this is also used to
    // form MediaError.message, do NOT use this for non-fatal errors to avoid
    // contaminating MediaError.message.
    MEDIALOG_ERROR,

    // Warning about non-fatal issues, e.g. quality of playback issues such as
    // audio/video out of sync.
    MEDIALOG_WARNING,

    // General info useful for Chromium and/or web developers, testers and even
    // users, e.g. audio/video codecs used in a playback instance.
    MEDIALOG_INFO,

    // Misc debug info for Chromium developers.
    MEDIALOG_DEBUG,
  };

  // Convert various enums to strings.
  static std::string MediaLogLevelToString(MediaLogLevel level);
  static MediaLogEvent::Type MediaLogLevelToEventType(MediaLogLevel level);
  static std::string EventTypeToString(MediaLogEvent::Type type);

  // Returns a string version of the status, unique to each PipelineStatus, and
  // not including any ':'. This makes it suitable for usage in
  // MediaError.message as the UA-specific-error-code.
  static std::string PipelineStatusToString(PipelineStatus status);

  static std::string BufferingStateToString(
      BufferingState state,
      BufferingStateChangeReason reason = BUFFERING_CHANGE_REASON_UNKNOWN);

  static std::string MediaEventToLogString(const MediaLogEvent& event);

  // Returns a string usable as part of a MediaError.message, for only
  // PIPELINE_ERROR or MEDIA_ERROR_LOG_ENTRY events, with any newlines replaced
  // with whitespace in the latter kind of events.
  static std::string MediaEventToMessageString(const MediaLogEvent& event);

  // Constructor is protected, see below.

  virtual ~MediaLog();

  // Add an event to this log.  Inheritors should override AddEventLocked to
  // do something.
  void AddEvent(std::unique_ptr<MediaLogEvent> event);

  // Returns a string usable as the contents of a MediaError.message.
  // This method returns an incomplete message if it is called before the
  // pertinent events for the error have been added to the log.
  // Note: The base class definition only produces empty messages. See
  // RenderMediaLog for where this method is meaningful.
  // Inheritors should override GetErrorMessageLocked().
  std::string GetErrorMessage();

  // Records the domain and registry of the current frame security origin to a
  // Rappor privacy-preserving metric. See:
  //   https://www.chromium.org/developers/design-documents/rappor
  // Inheritors should override RecordRapportWithSecurityOriginLocked().
  void RecordRapporWithSecurityOrigin(const std::string& metric);

  // Helper methods to create events and their parameters.
  std::unique_ptr<MediaLogEvent> CreateEvent(MediaLogEvent::Type type);
  std::unique_ptr<MediaLogEvent> CreateBooleanEvent(MediaLogEvent::Type type,
                                                    const std::string& property,
                                                    bool value);
  std::unique_ptr<MediaLogEvent> CreateCreatedEvent(
      const std::string& origin_url);
  std::unique_ptr<MediaLogEvent> CreateStringEvent(MediaLogEvent::Type type,
                                                   const std::string& property,
                                                   const std::string& value);
  std::unique_ptr<MediaLogEvent> CreateTimeEvent(MediaLogEvent::Type type,
                                                 const std::string& property,
                                                 base::TimeDelta value);
  std::unique_ptr<MediaLogEvent> CreateTimeEvent(MediaLogEvent::Type type,
                                                 const std::string& property,
                                                 double value);
  std::unique_ptr<MediaLogEvent> CreateLoadEvent(const std::string& url);
  std::unique_ptr<MediaLogEvent> CreatePipelineStateChangedEvent(
      PipelineImpl::State state);
  std::unique_ptr<MediaLogEvent> CreatePipelineErrorEvent(PipelineStatus error);
  std::unique_ptr<MediaLogEvent> CreateVideoSizeSetEvent(size_t width,
                                                         size_t height);
  std::unique_ptr<MediaLogEvent> CreateBufferingStateChangedEvent(
      const std::string& property,
      BufferingState state,
      BufferingStateChangeReason reason);

  // Report a log message at the specified log level.
  void AddLogEvent(MediaLogLevel level, const std::string& message);

  // Report a property change without an accompanying event.
  void SetStringProperty(const std::string& key, const std::string& value);
  void SetDoubleProperty(const std::string& key, double value);
  void SetBooleanProperty(const std::string& key, bool value);

  // Getter for |id_|. Used by MojoMediaLogService to construct MediaLogEvents
  // to log into this MediaLog. Also used in trace events to associate each
  // event with a specific media playback.
  int32_t id() const { return id_; }

  // Provide a MediaLog which can have a separate lifetime from this one, but
  // still write to the same log.  It is not guaranteed that this will log
  // forever; it might start silently discarding log messages if the original
  // log is closed by whoever owns it.
  virtual std::unique_ptr<MediaLog> Clone();

 protected:
  // Ensures only subclasses and factories (e.g. Clone()) can create MediaLog.
  MediaLog();

  // Methods that may be overridden by inheritors.  All calls may arrive on any
  // thread, but will be synchronized with respect to any other *Locked calls on
  // any other thread, and with any parent log invalidation.
  //
  // Please see the documentation for the corresponding public methods.
  virtual void AddEventLocked(std::unique_ptr<MediaLogEvent> event);
  virtual std::string GetErrorMessageLocked();
  virtual void RecordRapporWithSecurityOriginLocked(const std::string& metric);

  // Notify all child logs that they should stop working.  This should be called
  // to guarantee that no further calls into AddEvent should be allowed.
  // Further, since calls into this log may happen on any thread, it's important
  // to call this while the log is still in working order.  For example, calling
  // it immediately during destruction is a good idea.
  void InvalidateLog();

  struct ParentLogRecord : base::RefCountedThreadSafe<ParentLogRecord> {
    ParentLogRecord(MediaLog* log);

    // |lock_| protects the rest of this structure.
    base::Lock lock;

    // Original media log, or null.
    MediaLog* media_log GUARDED_BY(lock) = nullptr;

   protected:
    friend class base::RefCountedThreadSafe<ParentLogRecord>;
    virtual ~ParentLogRecord();

    DISALLOW_COPY_AND_ASSIGN(ParentLogRecord);
  };

  // Use |parent_log_record| instead of making a new one.
  MediaLog(scoped_refptr<ParentLogRecord> parent_log_record);

 private:
  // Allows MediaLogTest to construct MediaLog directly for testing.
  friend class MediaLogTest;
  FRIEND_TEST_ALL_PREFIXES(MediaLogTest, EventsAreForwarded);
  FRIEND_TEST_ALL_PREFIXES(MediaLogTest, EventsAreNotForwardedAfterInvalidate);

  enum : size_t {
    // Max length of URLs in Created/Load events. Exceeding triggers truncation.
    kMaxUrlLength = 1000,
  };

  // URLs (for Created and Load events) may be of arbitrary length from the
  // untrusted renderer. This method truncates to |kMaxUrlLength| before storing
  // the event, and sets the last 3 characters to an ellipsis.
  static std::string TruncateUrlString(std::string log_string);

  // The underlying media log.
  scoped_refptr<ParentLogRecord> parent_log_record_;

  // A unique (to this process) id for this MediaLog.
  int32_t id_;
  DISALLOW_COPY_AND_ASSIGN(MediaLog);
};

// Helper class to make it easier to use MediaLog like DVLOG().
class MEDIA_EXPORT LogHelper {
 public:
  LogHelper(MediaLog::MediaLogLevel level, MediaLog* media_log);
  LogHelper(MediaLog::MediaLogLevel level,
            const std::unique_ptr<MediaLog>& media_log);
  ~LogHelper();

  std::ostream& stream() { return stream_; }

 private:
  const MediaLog::MediaLogLevel level_;
  MediaLog* const media_log_;
  std::stringstream stream_;
};

// Provides a stringstream to collect a log entry to pass to the provided
// MediaLog at the requested level.
#define MEDIA_LOG(level, media_log) \
  LogHelper((MediaLog::MEDIALOG_##level), (media_log)).stream()

// Logs only while |count| < |max|, increments |count| for each log, and warns
// in the log if |count| has just reached |max|.
// Multiple short-circuit evaluations are involved in this macro:
// 1) LAZY_STREAM avoids wasteful MEDIA_LOG and evaluation of subsequent stream
//    arguments if |count| is >= |max|, and
// 2) the |condition| given to LAZY_STREAM itself short-circuits to prevent
//    incrementing |count| beyond |max|.
// Note that LAZY_STREAM guarantees exactly one evaluation of |condition|, so
// |count| will be incremented at most once each time this macro runs.
// The "|| true" portion of |condition| lets logging occur correctly when
// |count| < |max| and |count|++ is 0.
// TODO(wolenetz,chcunningham): Consider using a helper class instead of a macro
// to improve readability.
#define LIMITED_MEDIA_LOG(level, media_log, count, max)                       \
  LAZY_STREAM(MEDIA_LOG(level, media_log),                                    \
              (count) < (max) && ((count)++ || true))                         \
      << (((count) == (max)) ? "(Log limit reached. Further similar entries " \
                               "may be suppressed): "                         \
                             : "")

}  // namespace media

#endif  // MEDIA_BASE_MEDIA_LOG_H_
