/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <inttypes.h>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include "RecordFilter.h"
#include "command.h"
#include "event_attr.h"
#include "event_type.h"
#include "perf_regs.h"
#include "record.h"
#include "record_file.h"
#include "sample_tree.h"
#include "thread_tree.h"
#include "tracing.h"
#include "utils.h"

namespace simpleperf {
namespace {

using android::base::Split;

static std::set<std::string> branch_sort_keys = {
    "dso_from",
    "dso_to",
    "symbol_from",
    "symbol_to",
};
struct BranchFromEntry {
  const MapEntry* map;
  const Symbol* symbol;
  uint64_t vaddr_in_file;
  uint64_t flags;

  BranchFromEntry() : map(nullptr), symbol(nullptr), vaddr_in_file(0), flags(0) {}
};

struct SampleEntry {
  uint64_t time;
  uint64_t period;
  // accumuated when appearing in other sample's callchain
  uint64_t accumulated_period;
  uint64_t sample_count;
  int cpu;
  pid_t pid;
  pid_t tid;
  const char* thread_comm;
  const MapEntry* map;
  const Symbol* symbol;
  uint64_t vaddr_in_file;
  BranchFromEntry branch_from;
  // a callchain tree representing all callchains in the sample
  CallChainRoot<SampleEntry> callchain;
  // event counts for the sample
  std::vector<uint64_t> counts;
  // accumulated event counts for the sample
  std::vector<uint64_t> acc_counts;

  SampleEntry(uint64_t time, uint64_t period, uint64_t accumulated_period, uint64_t sample_count,
              int cpu, const ThreadEntry* thread, const MapEntry* map, const Symbol* symbol,
              uint64_t vaddr_in_file, const std::vector<uint64_t>& counts,
              const std::vector<uint64_t>& acc_counts)
      : time(time),
        period(period),
        accumulated_period(accumulated_period),
        sample_count(sample_count),
        cpu(cpu),
        pid(thread->pid),
        tid(thread->tid),
        thread_comm(thread->comm),
        map(map),
        symbol(symbol),
        vaddr_in_file(vaddr_in_file),
        counts(counts),
        acc_counts(acc_counts) {}

  // The data member 'callchain' can only move, not copy.
  SampleEntry(SampleEntry&&) = default;
  SampleEntry(SampleEntry&) = delete;

  uint64_t GetPeriod() const { return period; }
};

struct SampleTree {
  std::vector<SampleEntry*> samples;
  uint64_t total_samples;
  uint64_t total_period;
  uint64_t total_error_callchains;
  std::string event_name;
};

BUILD_COMPARE_VALUE_FUNCTION(CompareVaddrInFile, vaddr_in_file);
BUILD_DISPLAY_HEX64_FUNCTION(DisplayVaddrInFile, vaddr_in_file);

static std::string DisplayEventName(const SampleEntry*, const SampleTree* info) {
  return info->event_name;
}

struct AccInfo {
  uint64_t period = 0;
  std::vector<uint64_t> counts;
};

class ReportCmdSampleTreeBuilder : public SampleTreeBuilder<SampleEntry, AccInfo> {
 public:
  ReportCmdSampleTreeBuilder(const SampleComparator<SampleEntry>& sample_comparator,
                             ThreadTree* thread_tree,
                             const std::unordered_map<uint64_t, size_t>& event_id_to_attr_index)
      : SampleTreeBuilder(sample_comparator),
        thread_tree_(thread_tree),
        event_id_to_attr_index_(event_id_to_attr_index),
        total_samples_(0),
        total_period_(0),
        total_error_callchains_(0) {}

  void SetFilters(const std::unordered_set<int>& cpu_filter,
                  const std::unordered_set<std::string>& comm_filter,
                  const std::unordered_set<std::string>& dso_filter,
                  const std::unordered_set<std::string>& symbol_filter) {
    cpu_filter_ = cpu_filter;
    comm_filter_ = comm_filter;
    dso_filter_ = dso_filter;
    symbol_filter_ = symbol_filter;
  }

  void SetEventName(const std::string& event_name) { event_name_ = event_name; }

  SampleTree GetSampleTree() {
    AddCallChainDuplicateInfo();
    SampleTree sample_tree;
    sample_tree.samples = GetSamples();
    sample_tree.total_samples = total_samples_;
    sample_tree.total_period = total_period_;
    sample_tree.total_error_callchains = total_error_callchains_;
    sample_tree.event_name = event_name_;
    return sample_tree;
  }

  virtual void ReportCmdProcessSampleRecord(std::shared_ptr<SampleRecord>& r) {
    return ProcessSampleRecord(*r);
  }

  virtual void ReportCmdProcessSampleRecord(const SampleRecord& r) {
    return ProcessSampleRecord(r);
  }

 protected:
  virtual uint64_t GetPeriod(const SampleRecord& r) = 0;

  SampleEntry* CreateSample(const SampleRecord& r, bool in_kernel, AccInfo* acc_info) override {
    const ThreadEntry* thread = thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid);
    const MapEntry* map = thread_tree_->FindMap(thread, r.ip_data.ip, in_kernel);
    uint64_t vaddr_in_file;
    const Symbol* symbol = thread_tree_->FindSymbol(map, r.ip_data.ip, &vaddr_in_file);
    uint64_t period = GetPeriod(r);
    acc_info->period = period;
    std::vector<uint64_t> counts = GetCountsForSample(r);
    acc_info->counts = counts;
    std::unique_ptr<SampleEntry> sample(new SampleEntry(r.time_data.time, period, 0, 1, r.Cpu(),
                                                        thread, map, symbol, vaddr_in_file, counts,
                                                        counts));
    return InsertSample(std::move(sample));
  }

  SampleEntry* CreateBranchSample(const SampleRecord& r, const BranchStackItemType& item) override {
    const ThreadEntry* thread = thread_tree_->FindThreadOrNew(r.tid_data.pid, r.tid_data.tid);
    const MapEntry* from_map = thread_tree_->FindMap(thread, item.from);
    uint64_t from_vaddr_in_file;
    const Symbol* from_symbol = thread_tree_->FindSymbol(from_map, item.from, &from_vaddr_in_file);
    const MapEntry* to_map = thread_tree_->FindMap(thread, item.to);
    uint64_t to_vaddr_in_file;
    const Symbol* to_symbol = thread_tree_->FindSymbol(to_map, item.to, &to_vaddr_in_file);
    std::unique_ptr<SampleEntry> sample(new SampleEntry(r.time_data.time, r.period_data.period, 0,
                                                        1, r.Cpu(), thread, to_map, to_symbol,
                                                        to_vaddr_in_file, {}, {}));
    sample->branch_from.map = from_map;
    sample->branch_from.symbol = from_symbol;
    sample->branch_from.vaddr_in_file = from_vaddr_in_file;
    sample->branch_from.flags = item.flags;
    return InsertSample(std::move(sample));
  }

  SampleEntry* CreateCallChainSample(const ThreadEntry* thread, const SampleEntry* sample,
                                     uint64_t ip, bool in_kernel,
                                     const std::vector<SampleEntry*>& callchain,
                                     const AccInfo& acc_info) override {
    const MapEntry* map = thread_tree_->FindMap(thread, ip, in_kernel);
    if (thread_tree_->IsUnknownDso(map->dso)) {
      // The unwinders can give wrong ip addresses, which can't map to a valid dso. Skip them.
      total_error_callchains_++;
      return nullptr;
    }
    uint64_t vaddr_in_file;
    const Symbol* symbol = thread_tree_->FindSymbol(map, ip, &vaddr_in_file);
    std::unique_ptr<SampleEntry> callchain_sample(
        new SampleEntry(sample->time, 0, acc_info.period, 0, sample->cpu, thread, map, symbol,
                        vaddr_in_file, {}, acc_info.counts));
    callchain_sample->thread_comm = sample->thread_comm;
    return InsertCallChainSample(std::move(callchain_sample), callchain);
  }

  const ThreadEntry* GetThreadOfSample(SampleEntry* sample) override {
    return thread_tree_->FindThreadOrNew(sample->pid, sample->tid);
  }

  uint64_t GetPeriodForCallChain(const AccInfo& acc_info) override { return acc_info.period; }

  bool FilterSample(const SampleEntry* sample) override {
    if (!cpu_filter_.empty() && cpu_filter_.count(sample->cpu) == 0) {
      return false;
    }
    if (!comm_filter_.empty() && comm_filter_.count(sample->thread_comm) == 0) {
      return false;
    }
    if (!dso_filter_.empty() && dso_filter_.count(sample->map->dso->GetReportPath().data()) == 0) {
      return false;
    }
    if (!symbol_filter_.empty() && symbol_filter_.count(sample->symbol->DemangledName()) == 0) {
      return false;
    }
    return true;
  }

  void UpdateSummary(const SampleEntry* sample) override {
    total_samples_ += sample->sample_count;
    total_period_ += sample->period;
  }

  void MergeSample(SampleEntry* sample1, SampleEntry* sample2) override {
    sample1->period += sample2->period;
    sample1->accumulated_period += sample2->accumulated_period;
    sample1->sample_count += sample2->sample_count;
    if (sample1->counts.size() < sample2->counts.size()) {
      sample1->counts.resize(sample2->counts.size(), 0);
    }
    for (size_t i = 0; i < sample2->counts.size(); i++) {
      sample1->counts[i] += sample2->counts[i];
    }
    if (sample1->acc_counts.size() < sample2->acc_counts.size()) {
      sample1->acc_counts.resize(sample2->acc_counts.size(), 0);
    }
    for (size_t i = 0; i < sample2->acc_counts.size(); i++) {
      sample1->acc_counts[i] += sample2->acc_counts[i];
    }
  }

 private:
  std::vector<uint64_t> GetCountsForSample(const SampleRecord& r) {
    CHECK_EQ(r.read_data.counts.size(), r.read_data.ids.size());
    std::vector<uint64_t> res(r.read_data.counts.size(), 0);
    for (size_t i = 0; i < r.read_data.counts.size(); i++) {
      uint64_t event_id = r.read_data.ids[i];
      uint64_t count = r.read_data.counts[i];
      uint64_t& last_count = event_id_count_map_[event_id];
      uint64_t added_count = count - last_count;
      last_count = count;
      auto it = event_id_to_attr_index_.find(event_id);
      CHECK(it != event_id_to_attr_index_.end());
      CHECK_LT(it->second, res.size());
      // Count for the current sample is the added event count after generating the previous sample.
      res[it->second] = added_count;
    }
    return res;
  }

  ThreadTree* thread_tree_;
  const std::unordered_map<uint64_t, size_t>& event_id_to_attr_index_;

  std::unordered_set<int> cpu_filter_;
  std::unordered_set<std::string> comm_filter_;
  std::unordered_set<std::string> dso_filter_;
  std::unordered_set<std::string> symbol_filter_;

  uint64_t total_samples_;
  uint64_t total_period_;
  uint64_t total_error_callchains_;

  std::string event_name_;
  // Map from event_id to its last event count.
  std::unordered_map<uint64_t, uint64_t> event_id_count_map_;
};

// Build sample tree based on event count in each sample.
class EventCountSampleTreeBuilder : public ReportCmdSampleTreeBuilder {
 public:
  EventCountSampleTreeBuilder(const SampleComparator<SampleEntry>& sample_comparator,
                              ThreadTree* thread_tree,
                              const std::unordered_map<uint64_t, size_t>& event_id_to_attr_index)
      : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree, event_id_to_attr_index) {}

 protected:
  uint64_t GetPeriod(const SampleRecord& r) override { return r.period_data.period; }
};

// Build sample tree based on the time difference between current sample and next sample.
class TimestampSampleTreeBuilder : public ReportCmdSampleTreeBuilder {
 public:
  TimestampSampleTreeBuilder(const SampleComparator<SampleEntry>& sample_comparator,
                             ThreadTree* thread_tree,
                             const std::unordered_map<uint64_t, size_t>& event_id_to_attr_index)
      : ReportCmdSampleTreeBuilder(sample_comparator, thread_tree, event_id_to_attr_index) {}

  void ReportCmdProcessSampleRecord(std::shared_ptr<SampleRecord>& r) override {
    pid_t tid = static_cast<pid_t>(r->tid_data.tid);
    auto it = next_sample_cache_.find(tid);
    if (it == next_sample_cache_.end()) {
      next_sample_cache_[tid] = r;
    } else {
      std::shared_ptr<SampleRecord> cur = it->second;
      it->second = r;
      ProcessSampleRecord(*cur);
    }
  }

 protected:
  uint64_t GetPeriod(const SampleRecord& r) override {
    auto it = next_sample_cache_.find(r.tid_data.tid);
    CHECK(it != next_sample_cache_.end());
    // Normally the samples are sorted by time, but check here for safety.
    if (it->second->time_data.time > r.time_data.time) {
      return it->second->time_data.time - r.time_data.time;
    }
    return 1u;
  }

 private:
  std::unordered_map<pid_t, std::shared_ptr<SampleRecord>> next_sample_cache_;
};

struct SampleTreeBuilderOptions {
  SampleComparator<SampleEntry> comparator;
  ThreadTree* thread_tree;
  std::unordered_set<std::string> comm_filter;
  std::unordered_set<std::string> dso_filter;
  std::unordered_set<std::string> symbol_filter;
  std::unordered_set<int> cpu_filter;
  bool use_branch_address;
  bool accumulate_callchain;
  bool build_callchain;
  bool use_caller_as_callchain_root;
  bool trace_offcpu;

  std::unique_ptr<ReportCmdSampleTreeBuilder> CreateSampleTreeBuilder(
      const RecordFileReader& reader) {
    std::unique_ptr<ReportCmdSampleTreeBuilder> builder;
    if (trace_offcpu) {
      builder.reset(new TimestampSampleTreeBuilder(comparator, thread_tree, reader.EventIdMap()));
    } else {
      builder.reset(new EventCountSampleTreeBuilder(comparator, thread_tree, reader.EventIdMap()));
    }
    builder->SetFilters(cpu_filter, comm_filter, dso_filter, symbol_filter);
    builder->SetBranchSampleOption(use_branch_address);
    builder->SetCallChainSampleOptions(accumulate_callchain, build_callchain,
                                       use_caller_as_callchain_root);
    return builder;
  }
};

using ReportCmdSampleTreeSorter = SampleTreeSorter<SampleEntry>;
using ReportCmdSampleTreeDisplayer = SampleTreeDisplayer<SampleEntry, SampleTree>;

using ReportCmdCallgraphDisplayer = CallgraphDisplayer<SampleEntry, CallChainNode<SampleEntry>>;

class ReportCmdCallgraphDisplayerWithVaddrInFile : public ReportCmdCallgraphDisplayer {
 protected:
  std::string PrintSampleName(const SampleEntry* sample) override {
    return android::base::StringPrintf("%s [+0x%" PRIx64 "]", sample->symbol->DemangledName(),
                                       sample->vaddr_in_file);
  }
};

class ReportCommand : public Command {
 public:
  ReportCommand()
      : Command(
            "report", "report sampling information in perf.data",
            // clang-format off
"Usage: simpleperf report [options]\n"
"The default options are: -i perf.data --sort comm,pid,tid,dso,symbol.\n"
"-b    Use the branch-to addresses in sampled take branches instead of the\n"
"      instruction addresses. Only valid for perf.data recorded with -b/-j\n"
"      option.\n"
"--children    Print the overhead accumulated by appearing in the callchain.\n"
"              In the report, Children column shows overhead for a symbol and functions called\n"
"              by the symbol, while Self column shows overhead for the symbol itself.\n"
"--csv                     Report in csv format.\n"
"--csv-separator <sep>     Set separator for csv columns. Default is ','.\n"
"--full-callgraph  Print full call graph. Used with -g option. By default,\n"
"                  brief call graph is printed.\n"
"-g [callee|caller]    Print call graph. If callee mode is used, the graph\n"
"                      shows how functions are called from others. Otherwise,\n"
"                      the graph shows how functions call others.\n"
"                      Default is caller mode.\n"
"-i <file>  Specify path of record file, default is perf.data.\n"
"--kallsyms <file>     Set the file to read kernel symbols.\n"
"--max-stack <frames>  Set max stack frames shown when printing call graph.\n"
"-n         Print the sample count for each item.\n"
"--no-demangle         Don't demangle symbol names.\n"
"--no-show-ip          Don't show vaddr in file for unknown symbols.\n"
"-o report_file_name   Set report file name, default is stdout.\n"
"--percent-limit <percent>  Set min percentage in report entries and call graphs.\n"
"--print-event-count   Print event counts for each item. Additional events can be added by\n"
"                      --add-counter in record cmd.\n"
"--raw-period          Report period count instead of period percentage.\n"
"--sort key1,key2,...  Select keys used to group samples into report entries. Samples having\n"
"                      the same key values are aggregated into one report entry. Each report\n"
"                      entry is printed in one row, having columns to show key values.\n"
"                      Possible keys include:\n"
"                        pid             -- process id\n"
"                        tid             -- thread id\n"
"                        comm            -- thread name (can be changed during\n"
"                                           the lifetime of a thread)\n"
"                        dso             -- shared library\n"
"                        symbol          -- function name in the shared library\n"
"                        vaddr_in_file   -- virtual address in the shared\n"
"                                           library\n"
"                      Keys can only be used with -b option:\n"
"                        dso_from        -- shared library branched from\n"
"                        dso_to          -- shared library branched to\n"
"                        symbol_from     -- name of function branched from\n"
"                        symbol_to       -- name of function branched to\n"
"                      The default sort keys are:\n"
"                        comm,pid,tid,dso,symbol\n"
"--symfs <dir>         Look for files with symbols relative to this directory.\n"
"--vmlinux <file>      Parse kernel symbols from <file>.\n"
"\n"
"Sample filter options:\n"
"--comms comm1,comm2,...          Report only for threads with selected names.\n"
"--cpu   cpu_item1,cpu_item2,...  Report samples on the selected cpus. cpu_item can be cpu\n"
"                                 number like 1, or cpu range like 0-3.\n"
"--dsos dso1,dso2,...             Report only for selected dsos.\n"
"--pids pid1,pid2,...             Same as '--include-pid'.\n"
"--symbols symbol1;symbol2;...    Report only for selected symbols.\n"
"--tids tid1,tid2,...             Same as '--include-tid'.\n"
RECORD_FILTER_OPTION_HELP_MSG_FOR_REPORTING
            // clang-format on
            ),
        record_filename_("perf.data"),
        record_file_arch_(GetTargetArch()),
        use_branch_address_(false),
        accumulate_callchain_(false),
        print_callgraph_(false),
        callgraph_show_callee_(false),
        callgraph_max_stack_(UINT32_MAX),
        percent_limit_(0),
        raw_period_(false),
        brief_callgraph_(true),
        trace_offcpu_(false),
        sched_switch_attr_id_(0u),
        record_filter_(thread_tree_) {}

  bool Run(const std::vector<std::string>& args);

 private:
  bool ParseOptions(const std::vector<std::string>& args);
  bool BuildSampleComparatorAndDisplayer();
  bool ReadMetaInfoFromRecordFile();
  bool ReadEventAttrFromRecordFile();
  bool ReadFeaturesFromRecordFile();
  bool ReadSampleTreeFromRecordFile();
  bool ProcessRecord(std::unique_ptr<Record> record);
  void ProcessSampleRecordInTraceOffCpuMode(std::unique_ptr<Record> record, size_t attr_id);
  bool ProcessTracingData(const std::vector<char>& data);
  bool PrintReport();
  void PrintReportContext(FILE* fp);

  std::string record_filename_;
  ArchType record_file_arch_;
  std::unique_ptr<RecordFileReader> record_file_reader_;
  std::vector<perf_event_attr> event_attrs_;
  std::vector<std::string> attr_names_;
  ThreadTree thread_tree_;
  // Create a SampleTreeBuilder and SampleTree for each event_attr.
  std::vector<SampleTree> sample_tree_;
  SampleTreeBuilderOptions sample_tree_builder_options_;
  std::vector<std::unique_ptr<ReportCmdSampleTreeBuilder>> sample_tree_builder_;

  std::unique_ptr<ReportCmdSampleTreeSorter> sample_tree_sorter_;
  std::unique_ptr<ReportCmdSampleTreeDisplayer> sample_tree_displayer_;
  bool use_branch_address_;
  std::string record_cmdline_;
  bool accumulate_callchain_;
  bool print_callgraph_;
  bool callgraph_show_callee_;
  uint32_t callgraph_max_stack_;
  double percent_limit_;
  bool raw_period_;
  bool brief_callgraph_;
  bool trace_offcpu_;
  size_t sched_switch_attr_id_;
  bool report_csv_ = false;
  std::string csv_separator_ = ",";
  bool print_sample_count_ = false;
  bool print_event_count_ = false;
  std::vector<std::string> sort_keys_;
  std::string report_filename_;
  RecordFilter record_filter_;
};

bool ReportCommand::Run(const std::vector<std::string>& args) {
  // 1. Parse options.
  if (!ParseOptions(args)) {
    return false;
  }

  // 2. Read record file and build SampleTree.
  record_file_reader_ = RecordFileReader::CreateInstance(record_filename_);
  if (record_file_reader_ == nullptr) {
    return false;
  }
  if (!ReadMetaInfoFromRecordFile()) {
    return false;
  }
  if (!ReadEventAttrFromRecordFile()) {
    return false;
  }
  if (!BuildSampleComparatorAndDisplayer()) {
    return false;
  }
  // Read features first to prepare build ids used when building SampleTree.
  if (!ReadFeaturesFromRecordFile()) {
    return false;
  }
  ScopedCurrentArch scoped_arch(record_file_arch_);
  if (!ReadSampleTreeFromRecordFile()) {
    return false;
  }

  // 3. Show collected information.
  if (!PrintReport()) {
    return false;
  }

  return true;
}

bool ReportCommand::ParseOptions(const std::vector<std::string>& args) {
  OptionFormatMap option_formats = {
      {"-b", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--children", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--comms", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--cpu", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--csv", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--csv-separator", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--dsos", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--full-callgraph", {OptionValueType::NONE, OptionType::SINGLE}},
      {"-g", {OptionValueType::OPT_STRING, OptionType::SINGLE}},
      {"-i", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--kallsyms", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--max-stack", {OptionValueType::UINT, OptionType::SINGLE}},
      {"-n", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--no-demangle", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--no-show-ip", {OptionValueType::NONE, OptionType::SINGLE}},
      {"-o", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--percent-limit", {OptionValueType::DOUBLE, OptionType::SINGLE}},
      {"--pids", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--print-event-count", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--tids", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--raw-period", {OptionValueType::NONE, OptionType::SINGLE}},
      {"--sort", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--symbols", {OptionValueType::STRING, OptionType::MULTIPLE}},
      {"--symfs", {OptionValueType::STRING, OptionType::SINGLE}},
      {"--vmlinux", {OptionValueType::STRING, OptionType::SINGLE}},
  };
  OptionFormatMap record_filter_options = GetRecordFilterOptionFormats(false);
  option_formats.insert(record_filter_options.begin(), record_filter_options.end());

  OptionValueMap options;
  std::vector<std::pair<OptionName, OptionValue>> ordered_options;
  if (!PreprocessOptions(args, option_formats, &options, &ordered_options, nullptr)) {
    return false;
  }

  // Process options.
  use_branch_address_ = options.PullBoolValue("-b");
  accumulate_callchain_ = options.PullBoolValue("--children");
  for (const OptionValue& value : options.PullValues("--comms")) {
    std::vector<std::string> strs = Split(*value.str_value, ",");
    sample_tree_builder_options_.comm_filter.insert(strs.begin(), strs.end());
  }
  if (!record_filter_.ParseOptions(options)) {
    return false;
  }
  for (const OptionValue& value : options.PullValues("--cpu")) {
    if (auto cpus = GetCpusFromString(*value.str_value); cpus) {
      sample_tree_builder_options_.cpu_filter.insert(cpus->begin(), cpus->end());
    } else {
      return false;
    }
  }
  report_csv_ = options.PullBoolValue("--csv");
  options.PullStringValue("--csv-separator", &csv_separator_);
  for (const OptionValue& value : options.PullValues("--dsos")) {
    std::vector<std::string> strs = Split(*value.str_value, ",");
    sample_tree_builder_options_.dso_filter.insert(strs.begin(), strs.end());
  }
  brief_callgraph_ = !options.PullBoolValue("--full-callgraph");

  if (auto value = options.PullValue("-g"); value) {
    print_callgraph_ = true;
    accumulate_callchain_ = true;
    if (value->str_value != nullptr) {
      if (*value->str_value == "callee") {
        callgraph_show_callee_ = true;
      } else if (*value->str_value == "caller") {
        callgraph_show_callee_ = false;
      } else {
        LOG(ERROR) << "Unknown argument with -g option: " << *value->str_value;
        return false;
      }
    }
  }
  options.PullStringValue("-i", &record_filename_);
  if (auto value = options.PullValue("--kallsyms"); value) {
    std::string kallsyms;
    if (!android::base::ReadFileToString(*value->str_value, &kallsyms)) {
      LOG(ERROR) << "Can't read kernel symbols from " << *value->str_value;
      return false;
    }
    Dso::SetKallsyms(kallsyms);
  }
  if (!options.PullUintValue("--max-stack", &callgraph_max_stack_)) {
    return false;
  }
  print_sample_count_ = options.PullBoolValue("-n");

  Dso::SetDemangle(!options.PullBoolValue("--no-demangle"));

  if (!options.PullBoolValue("--no-show-ip")) {
    thread_tree_.ShowIpForUnknownSymbol();
  }

  options.PullStringValue("-o", &report_filename_);
  if (!options.PullDoubleValue("--percent-limit", &percent_limit_, 0)) {
    return false;
  }

  for (const OptionValue& value : options.PullValues("--pids")) {
    if (auto pids = GetTidsFromString(*value.str_value, false); pids) {
      record_filter_.AddPids(pids.value(), false);
    } else {
      return false;
    }
  }
  print_event_count_ = options.PullBoolValue("--print-event-count");
  for (const OptionValue& value : options.PullValues("--tids")) {
    if (auto tids = GetTidsFromString(*value.str_value, false); tids) {
      record_filter_.AddTids(tids.value(), false);
    } else {
      return false;
    }
  }
  raw_period_ = options.PullBoolValue("--raw-period");

  sort_keys_ = {"comm", "pid", "tid", "dso", "symbol"};
  if (auto value = options.PullValue("--sort"); value) {
    sort_keys_ = Split(*value->str_value, ",");
  }

  for (const OptionValue& value : options.PullValues("--symbols")) {
    std::vector<std::string> symbols = Split(*value.str_value, ";");
    sample_tree_builder_options_.symbol_filter.insert(symbols.begin(), symbols.end());
  }

  if (auto value = options.PullValue("--symfs"); value) {
    if (!Dso::SetSymFsDir(*value->str_value)) {
      return false;
    }
  }
  if (auto value = options.PullValue("--vmlinux"); value) {
    Dso::SetVmlinux(*value->str_value);
  }
  CHECK(options.values.empty());
  return true;
}

bool ReportCommand::BuildSampleComparatorAndDisplayer() {
  SampleDisplayer<SampleEntry, SampleTree> displayer;
  displayer.SetReportFormat(report_csv_, csv_separator_);
  SampleComparator<SampleEntry> comparator;

  if (accumulate_callchain_) {
    if (raw_period_) {
      displayer.AddDisplayFunction("Children", DisplayAccumulatedPeriod<SampleEntry>);
      displayer.AddDisplayFunction("Self", DisplaySelfPeriod<SampleEntry>);
    } else {
      displayer.AddDisplayFunction("Children", DisplayAccumulatedOverhead<SampleEntry, SampleTree>);
      displayer.AddDisplayFunction("Self", DisplaySelfOverhead<SampleEntry, SampleTree>);
    }
  } else {
    if (raw_period_) {
      displayer.AddDisplayFunction("Overhead", DisplaySelfPeriod<SampleEntry>);
    } else {
      displayer.AddDisplayFunction("Overhead", DisplaySelfOverhead<SampleEntry, SampleTree>);
    }
  }
  if (print_sample_count_) {
    displayer.AddDisplayFunction("Sample", DisplaySampleCount<SampleEntry>);
  }
  if (print_event_count_) {
    if (event_attrs_.size() == attr_names_.size()) {
      // Without additional counters, counts field isn't available. So print period field instead.
      if (accumulate_callchain_) {
        displayer.AddDisplayFunction("AccEventCount", DisplayAccumulatedPeriod<SampleEntry>);
        displayer.AddDisplayFunction("SelfEventCount", DisplaySelfPeriod<SampleEntry>);
      } else {
        displayer.AddDisplayFunction("EventCount", DisplaySelfPeriod<SampleEntry>);
      }
    } else {
      // With additional counters, print counts field.
      for (size_t i = 0; i < attr_names_.size(); i++) {
        auto self_event_count_fn = [i](const SampleEntry* s) {
          return i < s->counts.size() ? std::to_string(s->counts[i]) : "0";
        };
        auto acc_event_count_fn = [i](const SampleEntry* s) {
          return i < s->acc_counts.size() ? std::to_string(s->acc_counts[i]) : "0";
        };
        if (accumulate_callchain_) {
          displayer.AddDisplayFunction("AccEventCount_" + attr_names_[i], acc_event_count_fn);
          displayer.AddDisplayFunction("SelfEventCount_" + attr_names_[i], self_event_count_fn);
        } else {
          displayer.AddDisplayFunction("EventCount_" + attr_names_[i], self_event_count_fn);
        }
      }
    }
  }

  for (auto& key : sort_keys_) {
    if (!use_branch_address_ && branch_sort_keys.find(key) != branch_sort_keys.end()) {
      LOG(ERROR) << "sort key '" << key << "' can only be used with -b option.";
      return false;
    }
    if (key == "pid") {
      comparator.AddCompareFunction(ComparePid);
      displayer.AddDisplayFunction("Pid", DisplayPid<SampleEntry>);
    } else if (key == "tid") {
      comparator.AddCompareFunction(CompareTid);
      displayer.AddDisplayFunction("Tid", DisplayTid<SampleEntry>);
    } else if (key == "comm") {
      comparator.AddCompareFunction(CompareComm);
      displayer.AddDisplayFunction("Command", DisplayComm<SampleEntry>);
    } else if (key == "dso") {
      comparator.AddCompareFunction(CompareDso);
      displayer.AddDisplayFunction("Shared Object", DisplayDso<SampleEntry>);
    } else if (key == "symbol") {
      comparator.AddCompareFunction(CompareSymbol);
      displayer.AddDisplayFunction("Symbol", DisplaySymbol<SampleEntry>);
    } else if (key == "vaddr_in_file") {
      comparator.AddCompareFunction(CompareVaddrInFile);
      displayer.AddDisplayFunction("VaddrInFile", DisplayVaddrInFile<SampleEntry>);
    } else if (key == "dso_from") {
      comparator.AddCompareFunction(CompareDsoFrom);
      displayer.AddDisplayFunction("Source Shared Object", DisplayDsoFrom<SampleEntry>);
    } else if (key == "dso_to") {
      comparator.AddCompareFunction(CompareDso);
      displayer.AddDisplayFunction("Target Shared Object", DisplayDso<SampleEntry>);
    } else if (key == "symbol_from") {
      comparator.AddCompareFunction(CompareSymbolFrom);
      displayer.AddDisplayFunction("Source Symbol", DisplaySymbolFrom<SampleEntry>);
    } else if (key == "symbol_to") {
      comparator.AddCompareFunction(CompareSymbol);
      displayer.AddDisplayFunction("Target Symbol", DisplaySymbol<SampleEntry>);
    } else {
      LOG(ERROR) << "Unknown sort key: " << key;
      return false;
    }
  }

  // Reporting with --csv will add event count and event name columns. But if --print-event-count is
  // used, there is no need to duplicate printing event counts.
  if (report_csv_ && !print_event_count_) {
    if (accumulate_callchain_) {
      displayer.AddDisplayFunction("AccEventCount", DisplayAccumulatedPeriod<SampleEntry>);
      displayer.AddDisplayFunction("SelfEventCount", DisplaySelfPeriod<SampleEntry>);
    } else {
      displayer.AddDisplayFunction("EventCount", DisplaySelfPeriod<SampleEntry>);
    }
    displayer.AddDisplayFunction("EventName", DisplayEventName);
  }

  if (print_callgraph_) {
    bool has_symbol_key = false;
    bool has_vaddr_in_file_key = false;
    for (const auto& key : sort_keys_) {
      if (key == "symbol") {
        has_symbol_key = true;
      } else if (key == "vaddr_in_file") {
        has_vaddr_in_file_key = true;
      }
    }
    if (has_symbol_key) {
      if (has_vaddr_in_file_key) {
        displayer.AddExclusiveDisplayFunction(ReportCmdCallgraphDisplayerWithVaddrInFile());
      } else {
        displayer.AddExclusiveDisplayFunction(
            ReportCmdCallgraphDisplayer(callgraph_max_stack_, percent_limit_, brief_callgraph_));
      }
    }
  }

  if (percent_limit_ != 0.0) {
    displayer.SetFilterFunction([this](const SampleEntry* sample, const SampleTree* sample_tree) {
      uint64_t total_period = sample->period + sample->accumulated_period;
      return total_period >= sample_tree->total_period * percent_limit_ / 100.0;
    });
  }

  sample_tree_builder_options_.comparator = comparator;
  sample_tree_builder_options_.thread_tree = &thread_tree_;

  SampleComparator<SampleEntry> sort_comparator;
  sort_comparator.AddCompareFunction(CompareTotalPeriod);
  if (print_callgraph_) {
    sort_comparator.AddCompareFunction(CompareCallGraphDuplicated);
  }
  sort_comparator.AddCompareFunction(ComparePeriod);
  sort_comparator.AddComparator(comparator);
  sample_tree_sorter_.reset(new ReportCmdSampleTreeSorter(sort_comparator));
  sample_tree_displayer_.reset(new ReportCmdSampleTreeDisplayer(displayer));
  return true;
}

bool ReportCommand::ReadMetaInfoFromRecordFile() {
  auto& meta_info = record_file_reader_->GetMetaInfoFeature();
  if (auto it = meta_info.find("trace_offcpu"); it != meta_info.end()) {
    trace_offcpu_ = it->second == "true";
  }
  return record_filter_.CheckClock(record_file_reader_->GetClockId());
}

bool ReportCommand::ReadEventAttrFromRecordFile() {
  std::vector<EventAttrWithId> attrs = record_file_reader_->AttrSection();
  for (const auto& attr_with_id : attrs) {
    const perf_event_attr& attr = *attr_with_id.attr;
    attr_names_.emplace_back(GetEventNameByAttr(attr));

    // There are no samples for events added by --add-counter. So skip them.
    if ((attr.read_format & PERF_FORMAT_GROUP) && (attr.freq == 0) &&
        (attr.sample_period == INFINITE_SAMPLE_PERIOD)) {
      continue;
    }
    event_attrs_.emplace_back(attr);
  }
  if (use_branch_address_) {
    bool has_branch_stack = true;
    for (const auto& attr : event_attrs_) {
      if ((attr.sample_type & PERF_SAMPLE_BRANCH_STACK) == 0) {
        has_branch_stack = false;
        break;
      }
    }
    if (!has_branch_stack) {
      LOG(ERROR) << record_filename_ << " is not recorded with branch stack sampling option.";
      return false;
    }
  }
  if (trace_offcpu_) {
    size_t i;
    for (i = 0; i < event_attrs_.size(); ++i) {
      if (attr_names_[i] == "sched:sched_switch") {
        break;
      }
    }
    CHECK_NE(i, event_attrs_.size());
    sched_switch_attr_id_ = i;
  }
  return true;
}

bool ReportCommand::ReadFeaturesFromRecordFile() {
  if (!record_file_reader_->LoadBuildIdAndFileFeatures(thread_tree_)) {
    return false;
  }

  std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH);
  if (!arch.empty()) {
    record_file_arch_ = GetArchType(arch);
    if (record_file_arch_ == ARCH_UNSUPPORTED) {
      return false;
    }
  }

  std::vector<std::string> cmdline = record_file_reader_->ReadCmdlineFeature();
  if (!cmdline.empty()) {
    record_cmdline_ = android::base::Join(cmdline, ' ');
  }
  if (record_file_reader_->HasFeature(PerfFileFormat::FEAT_TRACING_DATA)) {
    std::vector<char> tracing_data;
    if (!record_file_reader_->ReadFeatureSection(PerfFileFormat::FEAT_TRACING_DATA,
                                                 &tracing_data)) {
      return false;
    }
    if (!ProcessTracingData(tracing_data)) {
      return false;
    }
  }
  return true;
}

bool ReportCommand::ReadSampleTreeFromRecordFile() {
  sample_tree_builder_options_.use_branch_address = use_branch_address_;
  sample_tree_builder_options_.accumulate_callchain = accumulate_callchain_;
  sample_tree_builder_options_.build_callchain = print_callgraph_;
  sample_tree_builder_options_.use_caller_as_callchain_root = !callgraph_show_callee_;
  sample_tree_builder_options_.trace_offcpu = trace_offcpu_;

  for (size_t i = 0; i < event_attrs_.size(); ++i) {
    sample_tree_builder_.push_back(
        sample_tree_builder_options_.CreateSampleTreeBuilder(*record_file_reader_));
    sample_tree_builder_.back()->SetEventName(attr_names_[i]);
    OfflineUnwinder* unwinder = sample_tree_builder_.back()->GetUnwinder();
    if (unwinder != nullptr) {
      unwinder->LoadMetaInfo(record_file_reader_->GetMetaInfoFeature());
    }
  }

  if (!record_file_reader_->ReadDataSection(
          [this](std::unique_ptr<Record> record) { return ProcessRecord(std::move(record)); })) {
    return false;
  }
  for (size_t i = 0; i < sample_tree_builder_.size(); ++i) {
    sample_tree_.push_back(sample_tree_builder_[i]->GetSampleTree());
    sample_tree_sorter_->Sort(sample_tree_.back().samples, print_callgraph_);
  }
  return true;
}

bool ReportCommand::ProcessRecord(std::unique_ptr<Record> record) {
  thread_tree_.Update(*record);
  if (record->type() == PERF_RECORD_SAMPLE) {
    if (!record_filter_.Check(static_cast<SampleRecord*>(record.get()))) {
      return true;
    }
    size_t attr_id = record_file_reader_->GetAttrIndexOfRecord(record.get());
    if (!trace_offcpu_) {
      sample_tree_builder_[attr_id]->ReportCmdProcessSampleRecord(
          *static_cast<SampleRecord*>(record.get()));
    } else {
      ProcessSampleRecordInTraceOffCpuMode(std::move(record), attr_id);
    }
  } else if (record->type() == PERF_RECORD_TRACING_DATA ||
             record->type() == SIMPLE_PERF_RECORD_TRACING_DATA) {
    const auto& r = *static_cast<TracingDataRecord*>(record.get());
    if (!ProcessTracingData(std::vector<char>(r.data, r.data + r.data_size))) {
      return false;
    }
  }
  return true;
}

void ReportCommand::ProcessSampleRecordInTraceOffCpuMode(std::unique_ptr<Record> record,
                                                         size_t attr_id) {
  std::shared_ptr<SampleRecord> r(static_cast<SampleRecord*>(record.release()));
  if (attr_id == sched_switch_attr_id_) {
    // If this sample belongs to sched_switch event, we should broadcast the offcpu info
    // to other event types.
    for (size_t i = 0; i < event_attrs_.size(); ++i) {
      if (i == sched_switch_attr_id_) {
        continue;
      }
      sample_tree_builder_[i]->ReportCmdProcessSampleRecord(r);
    }
  } else {
    sample_tree_builder_[attr_id]->ReportCmdProcessSampleRecord(r);
  }
}

bool ReportCommand::ProcessTracingData(const std::vector<char>& data) {
  auto tracing = Tracing::Create(data);
  if (!tracing) {
    return false;
  }
  for (size_t i = 0; i < event_attrs_.size(); i++) {
    if (event_attrs_[i].type == PERF_TYPE_TRACEPOINT) {
      uint64_t trace_event_id = event_attrs_[i].config;
      attr_names_[i] = tracing->GetTracingEventNameHavingId(trace_event_id);
    }
  }
  return true;
}

bool ReportCommand::PrintReport() {
  std::unique_ptr<FILE, decltype(&fclose)> file_handler(nullptr, fclose);
  FILE* report_fp = stdout;
  if (!report_filename_.empty()) {
    report_fp = fopen(report_filename_.c_str(), "w");
    if (report_fp == nullptr) {
      PLOG(ERROR) << "failed to open file " << report_filename_;
      return false;
    }
    file_handler.reset(report_fp);
  }
  PrintReportContext(report_fp);
  for (size_t i = 0; i < event_attrs_.size(); ++i) {
    if (trace_offcpu_ && i == sched_switch_attr_id_) {
      continue;
    }
    if (i != 0) {
      fprintf(report_fp, "\n");
    }
    SampleTree& sample_tree = sample_tree_[i];
    fprintf(report_fp, "Event: %s (type %u, config %llu)\n", attr_names_[i].c_str(),
            event_attrs_[i].type, event_attrs_[i].config);
    fprintf(report_fp, "Samples: %" PRIu64 "\n", sample_tree.total_samples);
    if (sample_tree.total_error_callchains != 0) {
      fprintf(report_fp, "Error Callchains: %" PRIu64 ", %f%%\n",
              sample_tree.total_error_callchains,
              sample_tree.total_error_callchains * 100.0 / sample_tree.total_samples);
    }
    const char* period_prefix = trace_offcpu_ ? "Time in ns" : "Event count";
    fprintf(report_fp, "%s: %" PRIu64 "\n\n", period_prefix, sample_tree.total_period);
    sample_tree_displayer_->DisplaySamples(report_fp, sample_tree.samples, &sample_tree);
  }
  fflush(report_fp);
  if (ferror(report_fp) != 0) {
    PLOG(ERROR) << "print report failed";
    return false;
  }
  return true;
}

void ReportCommand::PrintReportContext(FILE* report_fp) {
  if (!record_cmdline_.empty()) {
    fprintf(report_fp, "Cmdline: %s\n", record_cmdline_.c_str());
  }
  fprintf(report_fp, "Arch: %s\n", GetArchString(record_file_arch_).c_str());
}

}  // namespace

void RegisterReportCommand() {
  RegisterCommand("report", [] { return std::unique_ptr<Command>(new ReportCommand()); });
}

}  // namespace simpleperf
