/*
 * 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 <map>
#include <string>
#include <vector>

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

#include "command.h"
#include "event_attr.h"
#include "event_type.h"
#include "perf_regs.h"
#include "record.h"
#include "record_file.h"
#include "utils.h"

using namespace PerfFileFormat;

class DumpRecordCommand : public Command {
 public:
  DumpRecordCommand()
      : Command("dump", "dump perf record file",
                "Usage: simpleperf dumprecord [options] [perf_record_file]\n"
                "    Dump different parts of a perf record file. Default file is perf.data.\n"),
        record_filename_("perf.data"), record_file_arch_(GetBuildArch()) {
  }

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

 private:
  bool ParseOptions(const std::vector<std::string>& args);
  void DumpFileHeader();
  void DumpAttrSection();
  bool DumpDataSection();
  bool DumpFeatureSection();

  std::string record_filename_;
  std::unique_ptr<RecordFileReader> record_file_reader_;
  ArchType record_file_arch_;
};

bool DumpRecordCommand::Run(const std::vector<std::string>& args) {
  if (!ParseOptions(args)) {
    return false;
  }
  record_file_reader_ = RecordFileReader::CreateInstance(record_filename_);
  if (record_file_reader_ == nullptr) {
    return false;
  }
  std::string arch = record_file_reader_->ReadFeatureString(FEAT_ARCH);
  if (!arch.empty()) {
    record_file_arch_ = GetArchType(arch);
    if (record_file_arch_ == ARCH_UNSUPPORTED) {
      return false;
    }
  }
  ScopedCurrentArch scoped_arch(record_file_arch_);
  std::unique_ptr<ScopedEventTypes> scoped_event_types;
  if (record_file_reader_->HasFeature(PerfFileFormat::FEAT_META_INFO)) {
    std::unordered_map<std::string, std::string> meta_info;
    if (!record_file_reader_->ReadMetaInfoFeature(&meta_info)) {
      return false;
    }
    auto it = meta_info.find("event_type_info");
    if (it != meta_info.end()) {
      scoped_event_types.reset(new ScopedEventTypes(it->second));
    }
  }
  DumpFileHeader();
  DumpAttrSection();
  if (!DumpDataSection()) {
    return false;
  }
  return DumpFeatureSection();
}

bool DumpRecordCommand::ParseOptions(const std::vector<std::string>& args) {
  if (args.size() == 1) {
    record_filename_ = args[0];
  } else if (args.size() > 1) {
    ReportUnknownOption(args, 1);
    return false;
  }
  return true;
}

static const std::string GetFeatureNameOrUnknown(int feature) {
  std::string name = GetFeatureName(feature);
  return name.empty() ? android::base::StringPrintf("unknown_feature(%d)", feature) : name;
}

void DumpRecordCommand::DumpFileHeader() {
  const FileHeader& header = record_file_reader_->FileHeader();
  printf("magic: ");
  for (size_t i = 0; i < 8; ++i) {
    printf("%c", header.magic[i]);
  }
  printf("\n");
  printf("header_size: %" PRId64 "\n", header.header_size);
  if (header.header_size != sizeof(header)) {
    PLOG(WARNING) << "record file header size " << header.header_size
                  << "doesn't match expected header size " << sizeof(header);
  }
  printf("attr_size: %" PRId64 "\n", header.attr_size);
  if (header.attr_size != sizeof(FileAttr)) {
    PLOG(WARNING) << "record file attr size " << header.attr_size
                  << " doesn't match expected attr size " << sizeof(FileAttr);
  }
  printf("attrs[file section]: offset %" PRId64 ", size %" PRId64 "\n", header.attrs.offset,
         header.attrs.size);
  printf("data[file section]: offset %" PRId64 ", size %" PRId64 "\n", header.data.offset,
         header.data.size);
  printf("event_types[file section]: offset %" PRId64 ", size %" PRId64 "\n",
         header.event_types.offset, header.event_types.size);

  std::vector<int> features;
  for (size_t i = 0; i < FEAT_MAX_NUM; ++i) {
    size_t j = i / 8;
    size_t k = i % 8;
    if ((header.features[j] & (1 << k)) != 0) {
      features.push_back(i);
    }
  }
  for (auto& feature : features) {
    printf("feature: %s\n", GetFeatureNameOrUnknown(feature).c_str());
  }
}

void DumpRecordCommand::DumpAttrSection() {
  std::vector<EventAttrWithId> attrs = record_file_reader_->AttrSection();
  for (size_t i = 0; i < attrs.size(); ++i) {
    const auto& attr = attrs[i];
    printf("attr %zu:\n", i + 1);
    DumpPerfEventAttr(*attr.attr, 1);
    if (!attr.ids.empty()) {
      printf("  ids:");
      for (const auto& id : attr.ids) {
        printf(" %" PRId64, id);
      }
      printf("\n");
    }
  }
}

bool DumpRecordCommand::DumpDataSection() {
  ThreadTree thread_tree;
  thread_tree.ShowIpForUnknownSymbol();
  record_file_reader_->LoadBuildIdAndFileFeatures(thread_tree);

  auto get_symbol_function = [&](uint32_t pid, uint32_t tid, uint64_t ip, std::string& dso_name,
                                 std::string& symbol_name, uint64_t& vaddr_in_file,
                                 bool in_kernel) {
    ThreadEntry* thread = thread_tree.FindThreadOrNew(pid, tid);
    const MapEntry* map = thread_tree.FindMap(thread, ip, in_kernel);
    Dso* dso;
    const Symbol* symbol = thread_tree.FindSymbol(map, ip, &vaddr_in_file, &dso);
    dso_name = dso->Path();
    symbol_name = symbol->DemangledName();
  };

  auto record_callback = [&](std::unique_ptr<Record> r) {
    r->Dump();
    thread_tree.Update(*r);
    if (r->type() == PERF_RECORD_SAMPLE) {
      SampleRecord& sr = *static_cast<SampleRecord*>(r.get());
      bool in_kernel = sr.InKernel();
      if (sr.sample_type & PERF_SAMPLE_CALLCHAIN) {
        PrintIndented(1, "callchain:\n");
        for (size_t i = 0; i < sr.callchain_data.ip_nr; ++i) {
          if (sr.callchain_data.ips[i] >= PERF_CONTEXT_MAX) {
            if (sr.callchain_data.ips[i] == PERF_CONTEXT_USER) {
              in_kernel = false;
            }
            continue;
          }
          std::string dso_name;
          std::string symbol_name;
          uint64_t vaddr_in_file;
          get_symbol_function(sr.tid_data.pid, sr.tid_data.tid, sr.callchain_data.ips[i],
                              dso_name, symbol_name, vaddr_in_file, in_kernel);
          PrintIndented(2, "%s (%s[+%" PRIx64 "])\n", symbol_name.c_str(), dso_name.c_str(),
                        vaddr_in_file);
        }
      }
    } else if (r->type() == SIMPLE_PERF_RECORD_CALLCHAIN) {
      CallChainRecord& cr = *static_cast<CallChainRecord*>(r.get());
      PrintIndented(1, "callchain:\n");
      for (size_t i = 0; i < cr.ip_nr; ++i) {
        std::string dso_name;
        std::string symbol_name;
        uint64_t vaddr_in_file;
        get_symbol_function(cr.pid, cr.tid, cr.ips[i], dso_name, symbol_name, vaddr_in_file,
                            false);
        PrintIndented(2, "%s (%s[+%" PRIx64 "])\n", symbol_name.c_str(), dso_name.c_str(),
                      vaddr_in_file);
      }
    }
    return true;
  };
  return record_file_reader_->ReadDataSection(record_callback);
}

bool DumpRecordCommand::DumpFeatureSection() {
  std::map<int, SectionDesc> section_map = record_file_reader_->FeatureSectionDescriptors();
  for (const auto& pair : section_map) {
    int feature = pair.first;
    const auto& section = pair.second;
    printf("feature section for %s: offset %" PRId64 ", size %" PRId64 "\n",
           GetFeatureNameOrUnknown(feature).c_str(), section.offset, section.size);
    if (feature == FEAT_BUILD_ID) {
      std::vector<BuildIdRecord> records = record_file_reader_->ReadBuildIdFeature();
      for (auto& r : records) {
        r.Dump(1);
      }
    } else if (feature == FEAT_OSRELEASE) {
      std::string s = record_file_reader_->ReadFeatureString(feature);
      PrintIndented(1, "osrelease: %s\n", s.c_str());
    } else if (feature == FEAT_ARCH) {
      std::string s = record_file_reader_->ReadFeatureString(feature);
      PrintIndented(1, "arch: %s\n", s.c_str());
    } else if (feature == FEAT_CMDLINE) {
      std::vector<std::string> cmdline = record_file_reader_->ReadCmdlineFeature();
      PrintIndented(1, "cmdline: %s\n", android::base::Join(cmdline, ' ').c_str());
    } else if (feature == FEAT_FILE) {
      std::string file_path;
      uint32_t file_type;
      uint64_t min_vaddr;
      std::vector<Symbol> symbols;
      std::vector<uint64_t> dex_file_offsets;
      size_t read_pos = 0;
      PrintIndented(1, "file:\n");
      while (record_file_reader_->ReadFileFeature(read_pos, &file_path,
                                                  &file_type, &min_vaddr,
                                                  &symbols, &dex_file_offsets)) {
        PrintIndented(2, "file_path %s\n", file_path.c_str());
        PrintIndented(2, "file_type %s\n", DsoTypeToString(static_cast<DsoType>(file_type)));
        PrintIndented(2, "min_vaddr 0x%" PRIx64 "\n", min_vaddr);
        PrintIndented(2, "symbols:\n");
        for (const auto& symbol : symbols) {
          PrintIndented(3, "%s [0x%" PRIx64 "-0x%" PRIx64 "]\n", symbol.DemangledName(),
                        symbol.addr, symbol.addr + symbol.len);
        }
        if (file_type == static_cast<uint32_t>(DSO_DEX_FILE)) {
          PrintIndented(2, "dex_file_offsets:\n");
          for (uint64_t offset : dex_file_offsets) {
            PrintIndented(3, "0x%" PRIx64 "\n", offset);
          }
        }
      }
    } else if (feature == FEAT_META_INFO) {
      std::unordered_map<std::string, std::string> info_map;
      if (!record_file_reader_->ReadMetaInfoFeature(&info_map)) {
        return false;
      }
      PrintIndented(1, "meta_info:\n");
      for (auto& pair : info_map) {
        PrintIndented(2, "%s = %s\n", pair.first.c_str(), pair.second.c_str());
      }
    }
  }
  return true;
}

void RegisterDumpRecordCommand() {
  RegisterCommand("dump", [] { return std::unique_ptr<Command>(new DumpRecordCommand); });
}
