/*
 * Copyright (C) 2016 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.
 */

#ifndef SIMPLE_PERF_SAMPLE_DISPLAYER_H_
#define SIMPLE_PERF_SAMPLE_DISPLAYER_H_

#include <inttypes.h>

#include <functional>
#include <string>

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

// The display functions below are used to show items in a sample.

template <typename EntryT, typename InfoT>
std::string DisplayAccumulatedOverhead(const EntryT* sample,
                                       const InfoT* info) {
  uint64_t period = sample->period + sample->accumulated_period;
  uint64_t total_period = info->total_period;
  double percentage = (total_period != 0) ? 100.0 * period / total_period : 0.0;
  return android::base::StringPrintf("%.2f%%", percentage);
}

template <typename EntryT>
std::string DisplayAccumulatedPeriod(const EntryT* sample) {
  return android::base::StringPrintf("%" PRIu64, sample->period + sample->accumulated_period);
}

template <typename EntryT, typename InfoT>
std::string DisplaySelfOverhead(const EntryT* sample, const InfoT* info) {
  uint64_t period = sample->period;
  uint64_t total_period = info->total_period;
  double percentage = (total_period != 0) ? 100.0 * period / total_period : 0.0;
  return android::base::StringPrintf("%.2f%%", percentage);
}

#define BUILD_DISPLAY_UINT64_FUNCTION(function_name, display_part)        \
  template <typename EntryT>                                              \
  std::string function_name(const EntryT* sample) {                       \
    return android::base::StringPrintf("%" PRIu64, sample->display_part); \
  }

#define BUILD_DISPLAY_HEX64_FUNCTION(function_name, display_part)           \
  template <typename EntryT>                                                \
  std::string function_name(const EntryT* sample) {                         \
    return android::base::StringPrintf("0x%" PRIx64, sample->display_part); \
  }

BUILD_DISPLAY_UINT64_FUNCTION(DisplaySelfPeriod, period);
BUILD_DISPLAY_UINT64_FUNCTION(DisplaySampleCount, sample_count);

template <typename EntryT>
std::string DisplayPid(const EntryT* sample) {
  return android::base::StringPrintf("%d", sample->thread->pid);
}

template <typename EntryT>
std::string DisplayTid(const EntryT* sample) {
  return android::base::StringPrintf("%d", sample->thread->tid);
}

template <typename EntryT>
std::string DisplayComm(const EntryT* sample) {
  return sample->thread_comm;
}

template <typename EntryT>
std::string DisplayDso(const EntryT* sample) {
  return sample->map->dso->Path();
}

template <typename EntryT>
std::string DisplaySymbol(const EntryT* sample) {
  return sample->symbol->DemangledName();
}

template <typename EntryT>
std::string DisplayDsoFrom(const EntryT* sample) {
  return sample->branch_from.map->dso->Path();
}

template <typename EntryT>
std::string DisplaySymbolFrom(const EntryT* sample) {
  return sample->branch_from.symbol->DemangledName();
}

template <typename SampleT, typename CallChainNodeT>
class CallgraphDisplayer {
 private:
  static constexpr int SPACES_BETWEEN_CALLGRAPH_ENTRIES = 4;

 public:
  CallgraphDisplayer(uint32_t max_stack = UINT32_MAX,
                     double percent_limit = 0.0,
                     bool brief_callgraph = false)
      : max_stack_(max_stack), percent_limit_(percent_limit), brief_callgraph_(brief_callgraph) {}

  virtual ~CallgraphDisplayer() {}

  void operator()(FILE* fp, const SampleT* sample) {
    if (sample->callchain.children.empty()) {
      return;
    }
    std::string prefix = "       ";
    if (brief_callgraph_ && sample->callchain.duplicated) {
      fprintf(fp, "%s[skipped in brief callgraph mode]\n", prefix.c_str());
      return;
    }
    fprintf(fp, "%s|\n", prefix.c_str());
    fprintf(fp, "%s-- %s\n", prefix.c_str(), PrintSampleName(sample).c_str());
    prefix.append(3, ' ');
    for (size_t i = 0; i < sample->callchain.children.size(); ++i) {
      DisplayCallGraphEntry(fp, 1, prefix, sample->callchain.children[i],
                            sample->callchain.children_period + sample->GetPeriod(),
                            (i + 1 == sample->callchain.children.size()));
    }
  }

  void DisplayCallGraphEntry(FILE* fp, size_t depth, std::string prefix,
                             const std::unique_ptr<CallChainNodeT>& node,
                             uint64_t parent_period, bool last) {
    if (depth > max_stack_) {
      return;
    }
    std::string percentage_s = "-- ";
    if (node->period + node->children_period != parent_period) {
      double percentage =
          100.0 * (node->period + node->children_period) / parent_period;
      if (percentage < percent_limit_) {
        return;
      }
      percentage_s = android::base::StringPrintf("--%.2f%%-- ", percentage);
    }
    prefix += "|";
    fprintf(fp, "%s\n", prefix.c_str());
    if (last) {
      prefix.back() = ' ';
    }
    fprintf(fp, "%s%s%s\n", prefix.c_str(), percentage_s.c_str(),
            PrintSampleName(node->chain[0]).c_str());
    for (size_t i = 1; i < node->chain.size(); ++i) {
      fprintf(fp, "%s%*s%s\n", prefix.c_str(), static_cast<int>(percentage_s.size()), "",
              PrintSampleName(node->chain[i]).c_str());
    }
    prefix.append(SPACES_BETWEEN_CALLGRAPH_ENTRIES, ' ');
    if (!node->children.empty() && node->period != 0) {
      fprintf(fp, "%s|--%.2f%%-- [hit in function]\n", prefix.c_str(),
              100.0 * node->period / (node->period + node->children_period));
    }
    for (size_t i = 0; i < node->children.size(); ++i) {
      DisplayCallGraphEntry(fp, depth + 1, prefix, node->children[i],
                            node->children_period + node->period,
                            (i + 1 == node->children.size()));
    }
  }

 protected:
  virtual std::string PrintSampleName(const SampleT* sample) {
    return sample->symbol->DemangledName();
  }

 private:
  uint32_t max_stack_;
  double percent_limit_;
  bool brief_callgraph_;
};

// SampleDisplayer is a class using a collections of display functions to show a
// sample.

template <typename EntryT, typename InfoT>
class SampleDisplayer {
 public:
  typedef std::string (*display_sample_func_t)(const EntryT*);
  typedef std::string (*display_sample_with_info_func_t)(const EntryT*,
                                                         const InfoT*);
  using exclusive_display_sample_func_t =
      std::function<void(FILE*, const EntryT*)>;

 private:
  struct Item {
    std::string name;
    size_t width;
    display_sample_func_t func;
    display_sample_with_info_func_t func_with_info;
  };

 public:
  void SetInfo(const InfoT* info) { info_ = info; }

  void AddDisplayFunction(const std::string& name, display_sample_func_t func) {
    Item item;
    item.name = name;
    item.width = name.size();
    item.func = func;
    item.func_with_info = nullptr;
    display_v_.push_back(item);
  }

  void AddDisplayFunction(const std::string& name,
                          display_sample_with_info_func_t func_with_info) {
    Item item;
    item.name = name;
    item.width = name.size();
    item.func = nullptr;
    item.func_with_info = func_with_info;
    display_v_.push_back(item);
  }

  void AddExclusiveDisplayFunction(exclusive_display_sample_func_t func) {
    exclusive_display_v_.push_back(func);
  }

  void AdjustWidth(const EntryT* sample) {
    for (auto& item : display_v_) {
      std::string data = (item.func != nullptr)
                             ? item.func(sample)
                             : item.func_with_info(sample, info_);
      item.width = std::max(item.width, data.size());
    }
  }

  void PrintNames(FILE* fp) {
    for (size_t i = 0; i < display_v_.size(); ++i) {
      auto& item = display_v_[i];
      if (i != display_v_.size() - 1) {
        fprintf(fp, "%-*s  ", static_cast<int>(item.width), item.name.c_str());
      } else {
        fprintf(fp, "%s\n", item.name.c_str());
      }
    }
  }

  void PrintSample(FILE* fp, const EntryT* sample) {
    for (size_t i = 0; i < display_v_.size(); ++i) {
      auto& item = display_v_[i];
      std::string data = (item.func != nullptr)
                             ? item.func(sample)
                             : item.func_with_info(sample, info_);
      if (i != display_v_.size() - 1) {
        fprintf(fp, "%-*s  ", static_cast<int>(item.width), data.c_str());
      } else {
        fprintf(fp, "%s\n", data.c_str());
      }
    }
    for (auto& func : exclusive_display_v_) {
      func(fp, sample);
    }
  }

 private:
  const InfoT* info_;
  std::vector<Item> display_v_;
  std::vector<exclusive_display_sample_func_t> exclusive_display_v_;
};

#endif  // SIMPLE_PERF_SAMPLE_DISPLAYER_H_
