// Copyright (c) 2013 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 CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
#define CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_

#include <set>
#include <string>
#include <vector>

#include "base/lazy_instance.h"
#include "content/public/browser/tracing_controller.h"

namespace base {
class RefCountedString;
class RefCountedMemory;
}

namespace content {

class TraceMessageFilter;
class TracingUI;

class TracingControllerImpl : public TracingController {
 public:
  static TracingControllerImpl* GetInstance();

  // TracingController implementation.
  virtual bool GetCategories(
      const GetCategoriesDoneCallback& callback) override;
  virtual bool EnableRecording(
      const base::debug::CategoryFilter& category_filter,
      const base::debug::TraceOptions& trace_options,
      const EnableRecordingDoneCallback& callback) override;
  virtual bool DisableRecording(
      const scoped_refptr<TraceDataSink>& sink) override;
  virtual bool EnableMonitoring(
      const base::debug::CategoryFilter& category_filter,
      const base::debug::TraceOptions& trace_options,
      const EnableMonitoringDoneCallback& callback) override;
  virtual bool DisableMonitoring(
      const DisableMonitoringDoneCallback& callback) override;
  virtual void GetMonitoringStatus(
      bool* out_enabled,
      base::debug::CategoryFilter* out_category_filter,
      base::debug::TraceOptions* out_trace_options) override;
  virtual bool CaptureMonitoringSnapshot(
      const scoped_refptr<TraceDataSink>& sink) override;
  virtual bool GetTraceBufferPercentFull(
      const GetTraceBufferPercentFullCallback& callback) override;
  virtual bool SetWatchEvent(const std::string& category_name,
                             const std::string& event_name,
                             const WatchEventCallback& callback) override;
  virtual bool CancelWatchEvent() override;

  void RegisterTracingUI(TracingUI* tracing_ui);
  void UnregisterTracingUI(TracingUI* tracing_ui);

 private:
  typedef std::set<scoped_refptr<TraceMessageFilter> > TraceMessageFilterSet;

  friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
  friend class TraceMessageFilter;

  TracingControllerImpl();
  virtual ~TracingControllerImpl();

  bool can_enable_recording() const {
    return !is_recording_;
  }

  bool can_disable_recording() const {
    return is_recording_ && !trace_data_sink_.get();
  }

  bool can_enable_monitoring() const {
    return !is_monitoring_;
  }

  bool can_disable_monitoring() const {
    return is_monitoring_ && !monitoring_data_sink_.get();
  }

  bool can_get_trace_buffer_percent_full() const {
    return pending_trace_buffer_percent_full_callback_.is_null();
  }

  bool can_cancel_watch_event() const {
    return !watch_event_callback_.is_null();
  }

  // Methods for use by TraceMessageFilter.
  void AddTraceMessageFilter(TraceMessageFilter* trace_message_filter);
  void RemoveTraceMessageFilter(TraceMessageFilter* trace_message_filter);

  void OnTraceDataCollected(
      const scoped_refptr<base::RefCountedString>& events_str_ptr);
  void OnMonitoringTraceDataCollected(
      const scoped_refptr<base::RefCountedString>& events_str_ptr);

  // Callback of TraceLog::Flush() for the local trace.
  void OnLocalTraceDataCollected(
      const scoped_refptr<base::RefCountedString>& events_str_ptr,
      bool has_more_events);
  // Callback of TraceLog::FlushMonitoring() for the local trace.
  void OnLocalMonitoringTraceDataCollected(
      const scoped_refptr<base::RefCountedString>& events_str_ptr,
      bool has_more_events);

  void OnDisableRecordingAcked(
      TraceMessageFilter* trace_message_filter,
      const std::vector<std::string>& known_category_groups);

#if defined(OS_CHROMEOS) || defined(OS_WIN)
  void OnEndSystemTracingAcked(
      const scoped_refptr<base::RefCountedString>& events_str_ptr);
#endif

  void OnCaptureMonitoringSnapshotAcked(
      TraceMessageFilter* trace_message_filter);

  void OnTraceBufferPercentFullReply(
      TraceMessageFilter* trace_message_filter,
      float percent_full);

  void OnWatchEventMatched();

  void SetEnabledOnFileThread(
      const base::debug::CategoryFilter& category_filter,
      int mode,
      const base::debug::TraceOptions& trace_options,
      const base::Closure& callback);
  void SetDisabledOnFileThread(const base::Closure& callback);
  void OnEnableRecordingDone(const base::debug::CategoryFilter& category_filter,
                             const base::debug::TraceOptions& trace_options,
                             const EnableRecordingDoneCallback& callback);
  void OnDisableRecordingDone();
  void OnEnableMonitoringDone(
      const base::debug::CategoryFilter& category_filter,
      const base::debug::TraceOptions& trace_options,
      const EnableMonitoringDoneCallback& callback);
  void OnDisableMonitoringDone(const DisableMonitoringDoneCallback& callback);

  void OnMonitoringStateChanged(bool is_monitoring);

  TraceMessageFilterSet trace_message_filters_;

  // Pending acks for DisableRecording.
  int pending_disable_recording_ack_count_;
  TraceMessageFilterSet pending_disable_recording_filters_;
  // Pending acks for CaptureMonitoringSnapshot.
  int pending_capture_monitoring_snapshot_ack_count_;
  TraceMessageFilterSet pending_capture_monitoring_filters_;
  // Pending acks for GetTraceBufferPercentFull.
  int pending_trace_buffer_percent_full_ack_count_;
  TraceMessageFilterSet pending_trace_buffer_percent_full_filters_;
  float maximum_trace_buffer_percent_full_;

#if defined(OS_CHROMEOS) || defined(OS_WIN)
  bool is_system_tracing_;
#endif
  bool is_recording_;
  bool is_monitoring_;
  base::debug::TraceOptions trace_options_;

  GetCategoriesDoneCallback pending_get_categories_done_callback_;
  GetTraceBufferPercentFullCallback pending_trace_buffer_percent_full_callback_;

  std::string watch_category_name_;
  std::string watch_event_name_;
  WatchEventCallback watch_event_callback_;

  std::set<std::string> known_category_groups_;
  std::set<TracingUI*> tracing_uis_;
  scoped_refptr<TraceDataSink> trace_data_sink_;
  scoped_refptr<TraceDataSink> monitoring_data_sink_;
  DISALLOW_COPY_AND_ASSIGN(TracingControllerImpl);
};

}  // namespace content

#endif  // CONTENT_BROWSER_TRACING_TRACING_CONTROLLER_IMPL_H_
