// Copyright 2015 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 BASE_TRACE_EVENT_TRACE_CONFIG_H_
#define BASE_TRACE_EVENT_TRACE_CONFIG_H_

#include <stdint.h>

#include <memory>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

#include "base/base_export.h"
#include "base/gtest_prod_util.h"
#include "base/strings/string_piece.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/trace_config_category_filter.h"
#include "base/values.h"

namespace base {
namespace trace_event {

class ConvertableToTraceFormat;

// Options determines how the trace buffer stores data.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
enum TraceRecordMode {
  // Record until the trace buffer is full.
  RECORD_UNTIL_FULL,

  // Record until the user ends the trace. The trace buffer is a fixed size
  // and we use it as a ring buffer during recording.
  RECORD_CONTINUOUSLY,

  // Record until the trace buffer is full, but with a huge buffer size.
  RECORD_AS_MUCH_AS_POSSIBLE,

  // Echo to console. Events are discarded.
  ECHO_TO_CONSOLE,
};

class BASE_EXPORT TraceConfig {
 public:
  using StringList = std::vector<std::string>;

  // Specifies the memory dump config for tracing.
  // Used only when "memory-infra" category is enabled.
  struct BASE_EXPORT MemoryDumpConfig {
    MemoryDumpConfig();
    MemoryDumpConfig(const MemoryDumpConfig& other);
    ~MemoryDumpConfig();

    // Specifies the triggers in the memory dump config.
    struct Trigger {
      uint32_t min_time_between_dumps_ms;
      MemoryDumpLevelOfDetail level_of_detail;
      MemoryDumpType trigger_type;
    };

    // Specifies the configuration options for the heap profiler.
    struct HeapProfiler {
      // Default value for |breakdown_threshold_bytes|.
      enum { kDefaultBreakdownThresholdBytes = 1024 };

      HeapProfiler();

      // Reset the options to default.
      void Clear();

      uint32_t breakdown_threshold_bytes;
    };

    // Reset the values in the config.
    void Clear();

    void Merge(const MemoryDumpConfig& config);

    // Set of memory dump modes allowed for the tracing session. The explicitly
    // triggered dumps will be successful only if the dump mode is allowed in
    // the config.
    std::set<MemoryDumpLevelOfDetail> allowed_dump_modes;

    std::vector<Trigger> triggers;
    HeapProfiler heap_profiler_options;
  };

  class BASE_EXPORT ProcessFilterConfig {
   public:
    ProcessFilterConfig();
    explicit ProcessFilterConfig(
        const std::unordered_set<base::ProcessId>& included_process_ids);
    ProcessFilterConfig(const ProcessFilterConfig&);
    ~ProcessFilterConfig();

    bool empty() const { return included_process_ids_.empty(); }

    void Clear();
    void Merge(const ProcessFilterConfig&);

    void InitializeFromConfigDict(const base::DictionaryValue&);
    void ToDict(DictionaryValue*) const;

    bool IsEnabled(base::ProcessId) const;

    bool operator==(const ProcessFilterConfig& other) const {
      return included_process_ids_ == other.included_process_ids_;
    }

   private:
    std::unordered_set<base::ProcessId> included_process_ids_;
  };

  class BASE_EXPORT EventFilterConfig {
   public:
    EventFilterConfig(const std::string& predicate_name);
    EventFilterConfig(const EventFilterConfig& tc);

    ~EventFilterConfig();

    EventFilterConfig& operator=(const EventFilterConfig& rhs);

    void InitializeFromConfigDict(const base::DictionaryValue* event_filter);

    void SetCategoryFilter(const TraceConfigCategoryFilter& category_filter);

    void ToDict(DictionaryValue* filter_dict) const;

    bool GetArgAsSet(const char* key, std::unordered_set<std::string>*) const;

    bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;

    const std::string& predicate_name() const { return predicate_name_; }
    base::DictionaryValue* filter_args() const { return args_.get(); }
    const TraceConfigCategoryFilter& category_filter() const {
      return category_filter_;
    }

   private:
    std::string predicate_name_;
    TraceConfigCategoryFilter category_filter_;
    std::unique_ptr<base::DictionaryValue> args_;
  };
  typedef std::vector<EventFilterConfig> EventFilters;

  static std::string TraceRecordModeToStr(TraceRecordMode record_mode);

  TraceConfig();

  // Create TraceConfig object from category filter and trace options strings.
  //
  // |category_filter_string| is a comma-delimited list of category wildcards.
  // A category can have an optional '-' prefix to make it an excluded category.
  // All the same rules apply above, so for example, having both included and
  // excluded categories in the same list would not be supported.
  //
  // |trace_options_string| is a comma-delimited list of trace options.
  // Possible options are: "record-until-full", "record-continuously",
  // "record-as-much-as-possible", "trace-to-console", "enable-systrace" and
  // "enable-argument-filter".
  // The first 4 options are trace recoding modes and hence
  // mutually exclusive. If more than one trace recording modes appear in the
  // options_string, the last one takes precedence. If none of the trace
  // recording mode is specified, recording mode is RECORD_UNTIL_FULL.
  //
  // The trace option will first be reset to the default option
  // (record_mode set to RECORD_UNTIL_FULL, enable_systrace and
  // enable_argument_filter set to false) before options parsed from
  // |trace_options_string| are applied on it. If |trace_options_string| is
  // invalid, the final state of trace options is undefined.
  //
  // Example: TraceConfig("test_MyTest*", "record-until-full");
  // Example: TraceConfig("test_MyTest*,test_OtherStuff",
  //                      "record-continuously");
  // Example: TraceConfig("-excluded_category1,-excluded_category2",
  //                      "record-until-full, trace-to-console");
  //          would set ECHO_TO_CONSOLE as the recording mode.
  // Example: TraceConfig("-*,webkit", "");
  //          would disable everything but webkit; and use default options.
  // Example: TraceConfig("-webkit", "");
  //          would enable everything but webkit; and use default options.
  TraceConfig(StringPiece category_filter_string,
              StringPiece trace_options_string);

  TraceConfig(StringPiece category_filter_string, TraceRecordMode record_mode);

  // Create TraceConfig object from the trace config string.
  //
  // |config_string| is a dictionary formatted as a JSON string, containing both
  // category filters and trace options.
  //
  // Example:
  //   {
  //     "record_mode": "record-continuously",
  //     "enable_systrace": true,
  //     "enable_argument_filter": true,
  //     "included_categories": ["included",
  //                             "inc_pattern*",
  //                             "disabled-by-default-memory-infra"],
  //     "excluded_categories": ["excluded", "exc_pattern*"],
  //     "memory_dump_config": {
  //       "triggers": [
  //         {
  //           "mode": "detailed",
  //           "periodic_interval_ms": 2000
  //         }
  //       ]
  //     }
  //   }
  //
  // Note: memory_dump_config can be specified only if
  // disabled-by-default-memory-infra category is enabled.
  explicit TraceConfig(StringPiece config_string);

  // Functionally identical to the above, but takes a parsed dictionary as input
  // instead of its JSON serialization.
  explicit TraceConfig(const DictionaryValue& config);

  TraceConfig(const TraceConfig& tc);

  ~TraceConfig();

  TraceConfig& operator=(const TraceConfig& rhs);

  TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
  size_t GetTraceBufferSizeInEvents() const {
    return trace_buffer_size_in_events_;
  }
  bool IsSystraceEnabled() const { return enable_systrace_; }
  bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }

  void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
  void SetTraceBufferSizeInEvents(size_t size) {
    trace_buffer_size_in_events_ = size;
  }
  void EnableSystrace() { enable_systrace_ = true; }
  void EnableArgumentFilter() { enable_argument_filter_ = true; }

  // Writes the string representation of the TraceConfig. The string is JSON
  // formatted.
  std::string ToString() const;

  // Returns a copy of the TraceConfig wrapped in a ConvertableToTraceFormat
  std::unique_ptr<ConvertableToTraceFormat> AsConvertableToTraceFormat() const;

  // Write the string representation of the CategoryFilter part.
  std::string ToCategoryFilterString() const;

  // Returns true if at least one category in the list is enabled by this
  // trace config. This is used to determine if the category filters are
  // enabled in the TRACE_* macros.
  bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;

  // Merges config with the current TraceConfig
  void Merge(const TraceConfig& config);

  void Clear();

  // Clears and resets the memory dump config.
  void ResetMemoryDumpConfig(const MemoryDumpConfig& memory_dump_config);

  const TraceConfigCategoryFilter& category_filter() const {
    return category_filter_;
  }

  const MemoryDumpConfig& memory_dump_config() const {
    return memory_dump_config_;
  }

  const ProcessFilterConfig& process_filter_config() const {
    return process_filter_config_;
  }
  void SetProcessFilterConfig(const ProcessFilterConfig&);

  const EventFilters& event_filters() const { return event_filters_; }
  void SetEventFilters(const EventFilters& filter_configs) {
    event_filters_ = filter_configs;
  }

 private:
  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidLegacyFormat);
  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
                           TraceConfigFromInvalidLegacyStrings);

  // The default trace config, used when none is provided.
  // Allows all non-disabled-by-default categories through, except if they end
  // in the suffix 'Debug' or 'Test'.
  void InitializeDefault();

  // Initialize from a config dictionary.
  void InitializeFromConfigDict(const DictionaryValue& dict);

  // Initialize from a config string.
  void InitializeFromConfigString(StringPiece config_string);

  // Initialize from category filter and trace options strings
  void InitializeFromStrings(StringPiece category_filter_string,
                             StringPiece trace_options_string);

  void SetMemoryDumpConfigFromConfigDict(
      const DictionaryValue& memory_dump_config);
  void SetDefaultMemoryDumpConfig();

  void SetEventFiltersFromConfigList(const base::ListValue& event_filters);
  std::unique_ptr<DictionaryValue> ToDict() const;

  std::string ToTraceOptionsString() const;

  TraceRecordMode record_mode_;
  size_t trace_buffer_size_in_events_ = 0;  // 0 specifies default size
  bool enable_systrace_ : 1;
  bool enable_argument_filter_ : 1;

  TraceConfigCategoryFilter category_filter_;

  MemoryDumpConfig memory_dump_config_;
  ProcessFilterConfig process_filter_config_;

  EventFilters event_filters_;
};

}  // namespace trace_event
}  // namespace base

#endif  // BASE_TRACE_EVENT_TRACE_CONFIG_H_
