/*
 * Copyright (C) 2017 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 <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <memory>
#include <vector>

#include "android-base/stringprintf.h"

#include "base/stringpiece.h"

#include "dex_file.h"
#include "dex_ir.h"
#include "dex_ir_builder.h"
#include "pagemap/pagemap.h"
#include "runtime.h"
#include "vdex_file.h"

namespace art {

using android::base::StringPrintf;

static constexpr size_t kLineLength = 32;

static bool g_verbose = false;

// The width needed to print a file page offset (32-bit).
static constexpr int kPageCountWidth =
    static_cast<int>(std::numeric_limits<uint32_t>::digits10);
// Display the sections.
static constexpr char kSectionHeader[] = "Section name";

struct DexSectionInfo {
 public:
  std::string name;
  char letter;
};

static const std::map<uint16_t, DexSectionInfo> kDexSectionInfoMap = {
  { DexFile::kDexTypeHeaderItem, { "Header", 'H' } },
  { DexFile::kDexTypeStringIdItem, { "StringId", 'S' } },
  { DexFile::kDexTypeTypeIdItem, { "TypeId", 'T' } },
  { DexFile::kDexTypeProtoIdItem, { "ProtoId", 'P' } },
  { DexFile::kDexTypeFieldIdItem, { "FieldId", 'F' } },
  { DexFile::kDexTypeMethodIdItem, { "MethodId", 'M' } },
  { DexFile::kDexTypeClassDefItem, { "ClassDef", 'C' } },
  { DexFile::kDexTypeCallSiteIdItem, { "CallSiteId", 'z' } },
  { DexFile::kDexTypeMethodHandleItem, { "MethodHandle", 'Z' } },
  { DexFile::kDexTypeMapList, { "TypeMap", 'L' } },
  { DexFile::kDexTypeTypeList, { "TypeList", 't' } },
  { DexFile::kDexTypeAnnotationSetRefList, { "AnnotationSetReferenceItem", '1' } },
  { DexFile::kDexTypeAnnotationSetItem, { "AnnotationSetItem", '2' } },
  { DexFile::kDexTypeClassDataItem, { "ClassData", 'c' } },
  { DexFile::kDexTypeCodeItem, { "CodeItem", 'X' } },
  { DexFile::kDexTypeStringDataItem, { "StringData", 's' } },
  { DexFile::kDexTypeDebugInfoItem, { "DebugInfo", 'D' } },
  { DexFile::kDexTypeAnnotationItem, { "AnnotationItem", '3' } },
  { DexFile::kDexTypeEncodedArrayItem, { "EncodedArrayItem", 'E' } },
  { DexFile::kDexTypeAnnotationsDirectoryItem, { "AnnotationsDirectoryItem", '4' } }
};

class PageCount {
 public:
  PageCount() {
    for (auto it = kDexSectionInfoMap.begin(); it != kDexSectionInfoMap.end(); ++it) {
      map_[it->first] = 0;
    }
  }
  void Increment(uint16_t type) {
    map_[type]++;
  }
  size_t Get(uint16_t type) const {
    return map_.at(type);
  }
 private:
  std::map<uint16_t, size_t> map_;
  DISALLOW_COPY_AND_ASSIGN(PageCount);
};

class Printer {
 public:
  Printer() : section_header_width_(ComputeHeaderWidth()) {
  }

  void PrintHeader() const {
    std::cout << StringPrintf("%-*s %*s %*s %% of   %% of",
                              section_header_width_,
                              kSectionHeader,
                              kPageCountWidth,
                              "resident",
                              kPageCountWidth,
                              "total"
                              )
              << std::endl;
    std::cout << StringPrintf("%-*s %*s %*s sect.  total",
                              section_header_width_,
                              "",
                              kPageCountWidth,
                              "pages",
                              kPageCountWidth,
                              "pages")
              << std::endl;
  }

  void PrintOne(const char* name,
                size_t resident,
                size_t mapped,
                double percent_of_section,
                double percent_of_total) const {
    // 6.2 is sufficient to print 0-100% with two decimal places of accuracy.
    std::cout << StringPrintf("%-*s %*zd %*zd %6.2f %6.2f",
                              section_header_width_,
                              name,
                              kPageCountWidth,
                              resident,
                              kPageCountWidth,
                              mapped,
                              percent_of_section,
                              percent_of_total)
              << std::endl;
  }

  void PrintSkipLine() const { std::cout << std::endl; }

  // Computes the width of the section header column in the table (for fixed formatting).
  static int ComputeHeaderWidth() {
    int header_width = 0;
    for (const auto& pair : kDexSectionInfoMap) {
      const DexSectionInfo& section_info = pair.second;
      header_width = std::max(header_width, static_cast<int>(section_info.name.length()));
    }
    return header_width;
  }

 private:
  const int section_header_width_;
};

static void PrintLetterKey() {
  std::cout << "L pagetype" << std::endl;
  for (const auto& pair : kDexSectionInfoMap) {
    const DexSectionInfo& section_info = pair.second;
    std::cout << section_info.letter << " " << section_info.name.c_str() << std::endl;
  }
  std::cout << "* (Executable page resident)" << std::endl;
  std::cout << ". (Mapped page not resident)" << std::endl;
}

static char PageTypeChar(uint16_t type) {
  if (kDexSectionInfoMap.find(type) == kDexSectionInfoMap.end()) {
    return '-';
  }
  return kDexSectionInfoMap.find(type)->second.letter;
}

static uint16_t FindSectionTypeForPage(size_t page,
                                       const std::vector<dex_ir::DexFileSection>& sections) {
  for (const auto& section : sections) {
    size_t first_page_of_section = section.offset / kPageSize;
    // Only consider non-empty sections.
    if (section.size == 0) {
      continue;
    }
    // Attribute the page to the highest-offset section that starts before the page.
    if (first_page_of_section <= page) {
      return section.type;
    }
  }
  // If there's no non-zero sized section with an offset below offset we're looking for, it
  // must be the header.
  return DexFile::kDexTypeHeaderItem;
}

static void ProcessPageMap(uint64_t* pagemap,
                           size_t start,
                           size_t end,
                           const std::vector<dex_ir::DexFileSection>& sections,
                           PageCount* page_counts) {
  for (size_t page = start; page < end; ++page) {
    char type_char = '.';
    if (PM_PAGEMAP_PRESENT(pagemap[page])) {
      uint16_t type = FindSectionTypeForPage(page, sections);
      page_counts->Increment(type);
      type_char = PageTypeChar(type);
    }
    if (g_verbose) {
      std::cout << type_char;
      if ((page - start) % kLineLength == kLineLength - 1) {
        std::cout << std::endl;
      }
    }
  }
  if (g_verbose) {
    if ((end - start) % kLineLength != 0) {
      std::cout << std::endl;
    }
  }
}

static void DisplayDexStatistics(size_t start,
                                 size_t end,
                                 const PageCount& resident_pages,
                                 const std::vector<dex_ir::DexFileSection>& sections,
                                 Printer* printer) {
  // Compute the total possible sizes for sections.
  PageCount mapped_pages;
  DCHECK_GE(end, start);
  size_t total_mapped_pages = end - start;
  if (total_mapped_pages == 0) {
    return;
  }
  for (size_t page = start; page < end; ++page) {
    mapped_pages.Increment(FindSectionTypeForPage(page, sections));
  }
  size_t total_resident_pages = 0;
  printer->PrintHeader();
  for (size_t i = sections.size(); i > 0; --i) {
    const dex_ir::DexFileSection& section = sections[i - 1];
    const uint16_t type = section.type;
    const DexSectionInfo& section_info = kDexSectionInfoMap.find(type)->second;
    size_t pages_resident = resident_pages.Get(type);
    double percent_resident = 0;
    if (mapped_pages.Get(type) > 0) {
      percent_resident = 100.0 * pages_resident / mapped_pages.Get(type);
    }
    printer->PrintOne(section_info.name.c_str(),
                      pages_resident,
                      mapped_pages.Get(type),
                      percent_resident,
                      100.0 * pages_resident / total_mapped_pages);
    total_resident_pages += pages_resident;
  }
  double percent_of_total = 100.0 * total_resident_pages / total_mapped_pages;
  printer->PrintOne("GRAND TOTAL",
                    total_resident_pages,
                    total_mapped_pages,
                    percent_of_total,
                    percent_of_total);
  printer->PrintSkipLine();
}

static void ProcessOneDexMapping(uint64_t* pagemap,
                                 uint64_t map_start,
                                 const DexFile* dex_file,
                                 uint64_t vdex_start,
                                 Printer* printer) {
  uint64_t dex_file_start = reinterpret_cast<uint64_t>(dex_file->Begin());
  size_t dex_file_size = dex_file->Size();
  if (dex_file_start < vdex_start) {
    std::cerr << "Dex file start offset for "
              << dex_file->GetLocation().c_str()
              << " is incorrect: map start "
              << StringPrintf("%zx > dex start %zx\n", map_start, dex_file_start)
              << std::endl;
    return;
  }
  uint64_t start_page = (dex_file_start - vdex_start) / kPageSize;
  uint64_t start_address = start_page * kPageSize;
  uint64_t end_page = RoundUp(start_address + dex_file_size, kPageSize) / kPageSize;
  std::cout << "DEX "
            << dex_file->GetLocation().c_str()
            << StringPrintf(": %zx-%zx",
                            map_start + start_page * kPageSize,
                            map_start + end_page * kPageSize)
            << std::endl;
  // Build a list of the dex file section types, sorted from highest offset to lowest.
  std::vector<dex_ir::DexFileSection> sections;
  {
    std::unique_ptr<dex_ir::Header> header(dex_ir::DexIrBuilder(*dex_file));
    sections = dex_ir::GetSortedDexFileSections(header.get(),
                                                dex_ir::SortDirection::kSortDescending);
  }
  PageCount section_resident_pages;
  ProcessPageMap(pagemap, start_page, end_page, sections, &section_resident_pages);
  DisplayDexStatistics(start_page, end_page, section_resident_pages, sections, printer);
}

static bool DisplayMappingIfFromVdexFile(pm_map_t* map, Printer* printer) {
  // Confirm that the map is from a vdex file.
  static const char* suffixes[] = { ".vdex" };
  std::string vdex_name;
  bool found = false;
  for (size_t j = 0; j < sizeof(suffixes) / sizeof(suffixes[0]); ++j) {
    if (strstr(pm_map_name(map), suffixes[j]) != nullptr) {
      vdex_name = pm_map_name(map);
      found = true;
      break;
    }
  }
  if (!found) {
    return true;
  }
  // Extract all the dex files from the vdex file.
  std::string error_msg;
  std::unique_ptr<VdexFile> vdex(VdexFile::Open(vdex_name,
                                                false /*writeable*/,
                                                false /*low_4gb*/,
                                                false /*unquicken */,
                                                &error_msg /*out*/));
  if (vdex == nullptr) {
    std::cerr << "Could not open vdex file "
              << vdex_name
              << ": error "
              << error_msg
              << std::endl;
    return false;
  }

  std::vector<std::unique_ptr<const DexFile>> dex_files;
  if (!vdex->OpenAllDexFiles(&dex_files, &error_msg)) {
    std::cerr << "Dex files could not be opened for "
              << vdex_name
              << ": error "
              << error_msg
              << std::endl;
  }
  // Open the page mapping (one uint64_t per page) for the entire vdex mapping.
  uint64_t* pagemap;
  size_t len;
  if (pm_map_pagemap(map, &pagemap, &len) != 0) {
    std::cerr << "Error creating pagemap." << std::endl;
    return false;
  }
  // Process the dex files.
  std::cout << "MAPPING "
            << pm_map_name(map)
            << StringPrintf(": %zx-%zx", pm_map_start(map), pm_map_end(map))
            << std::endl;
  for (const auto& dex_file : dex_files) {
    ProcessOneDexMapping(pagemap,
                         pm_map_start(map),
                         dex_file.get(),
                         reinterpret_cast<uint64_t>(vdex->Begin()),
                         printer);
  }
  free(pagemap);
  return true;
}

static void ProcessOneOatMapping(uint64_t* pagemap, size_t size, Printer* printer) {
  size_t resident_page_count = 0;
  for (size_t page = 0; page < size; ++page) {
    char type_char = '.';
    if (PM_PAGEMAP_PRESENT(pagemap[page])) {
      ++resident_page_count;
      type_char = '*';
    }
    if (g_verbose) {
      std::cout << type_char;
      if (page % kLineLength == kLineLength - 1) {
        std::cout << std::endl;
      }
    }
  }
  if (g_verbose) {
    if (size % kLineLength != 0) {
      std::cout << std::endl;
    }
  }
  double percent_of_total = 100.0 * resident_page_count / size;
  printer->PrintHeader();
  printer->PrintOne("EXECUTABLE", resident_page_count, size, percent_of_total, percent_of_total);
  printer->PrintSkipLine();
}

static bool DisplayMappingIfFromOatFile(pm_map_t* map, Printer* printer) {
  // Confirm that the map is from a vdex file.
  static const char* suffixes[] = { ".odex", ".oat" };
  std::string vdex_name;
  bool found = false;
  for (size_t j = 0; j < sizeof(suffixes) / sizeof(suffixes[0]); ++j) {
    if (strstr(pm_map_name(map), suffixes[j]) != nullptr) {
      vdex_name = pm_map_name(map);
      found = true;
      break;
    }
  }
  if (!found) {
    return true;
  }
  // Open the page mapping (one uint64_t per page) for the entire vdex mapping.
  uint64_t* pagemap;
  size_t len;
  if (pm_map_pagemap(map, &pagemap, &len) != 0) {
    std::cerr << "Error creating pagemap." << std::endl;
    return false;
  }
  // Process the dex files.
  std::cout << "MAPPING "
            << pm_map_name(map)
            << StringPrintf(": %zx-%zx", pm_map_start(map), pm_map_end(map))
            << std::endl;
  ProcessOneOatMapping(pagemap, len, printer);
  free(pagemap);
  return true;
}

static bool FilterByNameContains(const std::string& mapped_file_name,
                                 const std::vector<std::string>& name_filters) {
  // If no filters were set, everything matches.
  if (name_filters.empty()) {
    return true;
  }
  for (const auto& name_contains : name_filters) {
    if (mapped_file_name.find(name_contains) != std::string::npos) {
      return true;
    }
  }
  return false;
}

static void Usage(const char* cmd) {
  std::cerr << "Usage: " << cmd << " [options] pid" << std::endl
            << "    --contains=<string>:  Display sections containing string." << std::endl
            << "    --help:               Shows this message." << std::endl
            << "    --verbose:            Makes displays verbose." << std::endl;
  PrintLetterKey();
}

static int DexDiagMain(int argc, char* argv[]) {
  if (argc < 2) {
    Usage(argv[0]);
    return EXIT_FAILURE;
  }

  std::vector<std::string> name_filters;
  // TODO: add option to track usage by class name, etc.
  for (int i = 1; i < argc - 1; ++i) {
    const StringPiece option(argv[i]);
    if (option == "--help") {
      Usage(argv[0]);
      return EXIT_SUCCESS;
    } else if (option == "--verbose") {
      g_verbose = true;
    } else if (option.starts_with("--contains=")) {
      std::string contains(option.substr(strlen("--contains=")).data());
      name_filters.push_back(contains);
    } else {
      Usage(argv[0]);
      return EXIT_FAILURE;
    }
  }

  // Art specific set up.
  InitLogging(argv, Runtime::Aborter);
  MemMap::Init();

  pid_t pid;
  char* endptr;
  pid = (pid_t)strtol(argv[argc - 1], &endptr, 10);
  if (*endptr != '\0' || kill(pid, 0) != 0) {
    std::cerr << StringPrintf("Invalid PID \"%s\".\n", argv[argc - 1]) << std::endl;
    return EXIT_FAILURE;
  }

  // get libpagemap kernel information.
  pm_kernel_t* ker;
  if (pm_kernel_create(&ker) != 0) {
    std::cerr << "Error creating kernel interface -- does this kernel have pagemap?" << std::endl;
    return EXIT_FAILURE;
  }

  // get libpagemap process information.
  pm_process_t* proc;
  if (pm_process_create(ker, pid, &proc) != 0) {
    std::cerr << "Error creating process interface -- does process "
              << pid
              << " really exist?"
              << std::endl;
    return EXIT_FAILURE;
  }

  // Get the set of mappings by the specified process.
  pm_map_t** maps;
  size_t num_maps;
  if (pm_process_maps(proc, &maps, &num_maps) != 0) {
    std::cerr << "Error listing maps." << std::endl;
    return EXIT_FAILURE;
  }

  // Process the mappings that are due to DEX files.
  Printer printer;
  for (size_t i = 0; i < num_maps; ++i) {
    std::string mapped_file_name = pm_map_name(maps[i]);
    // Filter by name contains options (if any).
    if (!FilterByNameContains(mapped_file_name, name_filters)) {
      continue;
    }
    if (!DisplayMappingIfFromVdexFile(maps[i], &printer)) {
      return EXIT_FAILURE;
    } else if (!DisplayMappingIfFromOatFile(maps[i], &printer)) {
      return EXIT_FAILURE;
    }
  }

  return EXIT_SUCCESS;
}

}  // namespace art

int main(int argc, char* argv[]) {
  return art::DexDiagMain(argc, argv);
}
