/*
 * 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 "Debug.h"

#include <androidfw/TypeWrappers.h>
#include <androidfw/Util.h>
#include <format/binary/ResChunkPullParser.h>

#include <algorithm>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <vector>

#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "idmap2/Policies.h"
#include "text/Printer.h"
#include "util/Util.h"

using ::aapt::text::Printer;
using ::android::StringPiece;
using ::android::base::StringPrintf;

using android::idmap2::policy::kPolicyStringToFlag;

using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;

namespace aapt {

namespace {

class ValueHeadlinePrinter : public ConstValueVisitor {
 public:
  using ConstValueVisitor::Visit;

  explicit ValueHeadlinePrinter(const std::string& package, Printer* printer)
      : package_(package), printer_(printer) {
  }

  void Visit(const Attribute* attr) override {
    printer_->Print("(attr) type=");
    printer_->Print(attr->MaskString());
    if (!attr->symbols.empty()) {
      printer_->Print(StringPrintf(" size=%zd", attr->symbols.size()));
    }
  }

  void Visit(const Style* style) override {
    printer_->Print(StringPrintf("(style) size=%zd", style->entries.size()));
    if (style->parent) {
      printer_->Print(" parent=");

      const Reference& parent_ref = style->parent.value();
      if (parent_ref.name) {
        if (parent_ref.private_reference) {
          printer_->Print("*");
        }

        const ResourceName& parent_name = parent_ref.name.value();
        if (package_ != parent_name.package) {
          printer_->Print(parent_name.package);
          printer_->Print(":");
        }
        printer_->Print(parent_name.type.to_string());
        printer_->Print("/");
        printer_->Print(parent_name.entry);
        if (parent_ref.id) {
          printer_->Print(" (");
          printer_->Print(parent_ref.id.value().to_string());
          printer_->Print(")");
        }
      } else if (parent_ref.id) {
        printer_->Print(parent_ref.id.value().to_string());
      } else {
        printer_->Print("???");
      }
    }
  }

  void Visit(const Array* array) override {
    printer_->Print(StringPrintf("(array) size=%zd", array->elements.size()));
  }

  void Visit(const Plural* plural) override {
    size_t count = std::count_if(plural->values.begin(), plural->values.end(),
                                 [](const std::unique_ptr<Item>& v) { return v != nullptr; });
    printer_->Print(StringPrintf("(plurals) size=%zd", count));
  }

  void Visit(const Styleable* styleable) override {
    printer_->Println(StringPrintf("(styleable) size=%zd", styleable->entries.size()));
  }

  void VisitItem(const Item* item) override {
    // Pretty much guaranteed to be one line.
    if (const Reference* ref = ValueCast<Reference>(item)) {
      // Special case Reference so that we can print local resources without a package name.
      ref->PrettyPrint(package_, printer_);
    } else {
      item->PrettyPrint(printer_);
    }
  }

 private:
  std::string package_;
  Printer* printer_;
};

class ValueBodyPrinter : public ConstValueVisitor {
 public:
  using ConstValueVisitor::Visit;

  explicit ValueBodyPrinter(const std::string& package, Printer* printer)
      : package_(package), printer_(printer) {
  }

  void Visit(const Attribute* attr) override {
    constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM | android::ResTable_map::TYPE_FLAGS;
    if (attr->type_mask & kMask) {
      for (const auto& symbol : attr->symbols) {
        if (symbol.symbol.name) {
          printer_->Print(symbol.symbol.name.value().entry);

          if (symbol.symbol.id) {
            printer_->Print("(");
            printer_->Print(symbol.symbol.id.value().to_string());
            printer_->Print(")");
          }
        } else if (symbol.symbol.id) {
          printer_->Print(symbol.symbol.id.value().to_string());
        } else {
          printer_->Print("???");
        }

        printer_->Println(StringPrintf("=0x%08x", symbol.value));
      }
    }
  }

  void Visit(const Style* style) override {
    for (const auto& entry : style->entries) {
      if (entry.key.name) {
        const ResourceName& name = entry.key.name.value();
        if (!name.package.empty() && name.package != package_) {
          printer_->Print(name.package);
          printer_->Print(":");
        }
        printer_->Print(name.entry);

        if (entry.key.id) {
          printer_->Print("(");
          printer_->Print(entry.key.id.value().to_string());
          printer_->Print(")");
        }
      } else if (entry.key.id) {
        printer_->Print(entry.key.id.value().to_string());
      } else {
        printer_->Print("???");
      }

      printer_->Print("=");
      PrintItem(*entry.value);
      printer_->Println();
    }
  }

  void Visit(const Array* array) override {
    const size_t count = array->elements.size();
    printer_->Print("[");
    for (size_t i = 0u; i < count; i++) {
      if (i != 0u && i % 4u == 0u) {
        printer_->Println();
        printer_->Print(" ");
      }
      PrintItem(*array->elements[i]);
      if (i != count - 1) {
        printer_->Print(", ");
      }
    }
    printer_->Println("]");
  }

  void Visit(const Plural* plural) override {
    constexpr std::array<const char*, Plural::Count> kPluralNames = {
        {"zero", "one", "two", "few", "many", "other"}};

    for (size_t i = 0; i < Plural::Count; i++) {
      if (plural->values[i] != nullptr) {
        printer_->Print(StringPrintf("%s=", kPluralNames[i]));
        PrintItem(*plural->values[i]);
        printer_->Println();
      }
    }
  }

  void Visit(const Styleable* styleable) override {
    for (const auto& attr : styleable->entries) {
      if (attr.name) {
        const ResourceName& name = attr.name.value();
        if (!name.package.empty() && name.package != package_) {
          printer_->Print(name.package);
          printer_->Print(":");
        }
        printer_->Print(name.entry);

        if (attr.id) {
          printer_->Print("(");
          printer_->Print(attr.id.value().to_string());
          printer_->Print(")");
        }
      }

      if (attr.id) {
        printer_->Print(attr.id.value().to_string());
      }
      printer_->Println();
    }
  }

  void VisitItem(const Item* item) override {
    // Intentionally left empty, we already printed the Items.
  }

 private:
  void PrintItem(const Item& item) {
    if (const Reference* ref = ValueCast<Reference>(&item)) {
      // Special case Reference so that we can print local resources without a package name.
      ref->PrettyPrint(package_, printer_);
    } else {
      item.PrettyPrint(printer_);
    }
  }

  std::string package_;
  Printer* printer_;
};

}  // namespace

void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options,
                       Printer* printer) {
  const auto table_view = table.GetPartitionedView();
  for (const auto& package : table_view.packages) {
    ValueHeadlinePrinter headline_printer(package.name, printer);
    ValueBodyPrinter body_printer(package.name, printer);

    printer->Print("Package name=");
    printer->Print(package.name);
    if (package.id) {
      printer->Print(StringPrintf(" id=%02x", package.id.value()));
    }
    printer->Println();

    printer->Indent();
    for (const auto& type : package.types) {
      printer->Print("type ");
      printer->Print(type.named_type.to_string());
      if (type.id) {
        printer->Print(StringPrintf(" id=%02x", type.id.value()));
      }
      printer->Println(StringPrintf(" entryCount=%zd", type.entries.size()));

      printer->Indent();
      for (const ResourceTableEntryView& entry : type.entries) {
        printer->Print("resource ");
        printer->Print(ResourceId(package.id.value_or(0), type.id.value_or(0), entry.id.value_or(0))
                           .to_string());
        printer->Print(" ");

        // Write the name without the package (this is obvious and too verbose).
        printer->Print(type.named_type.to_string());
        printer->Print("/");
        printer->Print(entry.name);

        switch (entry.visibility.level) {
          case Visibility::Level::kPublic:
            printer->Print(" PUBLIC");
            break;
          case Visibility::Level::kPrivate:
            printer->Print(" _PRIVATE_");
            break;
          case Visibility::Level::kUndefined:
            // Print nothing.
            break;
        }

        if (entry.visibility.staged_api) {
          printer->Print(" STAGED");
        }

        if (entry.overlayable_item) {
          printer->Print(" OVERLAYABLE");
        }

        if (entry.staged_id) {
          printer->Print(" STAGED_ID=");
          printer->Print(entry.staged_id.value().id.to_string());
        }

        printer->Println();

        if (options.show_values) {
          printer->Indent();
          for (const auto& value : entry.values) {
            printer->Print("(");
            printer->Print(value->config.to_string());
            printer->Print(") ");
            value->value->Accept(&headline_printer);
            if (options.show_sources && !value->value->GetSource().path.empty()) {
              printer->Print(" src=");
              printer->Print(value->value->GetSource().to_string());
            }
            printer->Println();
            printer->Indent();
            value->value->Accept(&body_printer);
            printer->Undent();
          }
          printer->Undent();
        }
      }
      printer->Undent();
    }
    printer->Undent();
  }
}

static size_t GetNodeIndex(const std::vector<ResourceName>& names, const ResourceName& name) {
  auto iter = std::lower_bound(names.begin(), names.end(), name);
  CHECK(iter != names.end());
  CHECK(*iter == name);
  return std::distance(names.begin(), iter);
}

void Debug::PrintStyleGraph(ResourceTable* table, const ResourceName& target_style) {
  std::map<ResourceName, std::set<ResourceName>> graph;

  std::queue<ResourceName> styles_to_visit;
  styles_to_visit.push(target_style);
  for (; !styles_to_visit.empty(); styles_to_visit.pop()) {
    const ResourceName& style_name = styles_to_visit.front();
    std::set<ResourceName>& parents = graph[style_name];
    if (!parents.empty()) {
      // We've already visited this style.
      continue;
    }

    std::optional<ResourceTable::SearchResult> result = table->FindResource(style_name);
    if (result) {
      ResourceEntry* entry = result.value().entry;
      for (const auto& value : entry->values) {
        if (Style* style = ValueCast<Style>(value->value.get())) {
          if (style->parent && style->parent.value().name) {
            parents.insert(style->parent.value().name.value());
            styles_to_visit.push(style->parent.value().name.value());
          }
        }
      }
    }
  }

  std::vector<ResourceName> names;
  for (const auto& entry : graph) {
    names.push_back(entry.first);
  }

  std::cout << "digraph styles {\n";
  for (const auto& name : names) {
    std::cout << "  node_" << GetNodeIndex(names, name) << " [label=\"" << name << "\"];\n";
  }

  for (const auto& entry : graph) {
    const ResourceName& style_name = entry.first;
    size_t style_node_index = GetNodeIndex(names, style_name);

    for (const auto& parent_name : entry.second) {
      std::cout << "  node_" << style_node_index << " -> "
                << "node_" << GetNodeIndex(names, parent_name) << ";\n";
    }
  }

  std::cout << "}" << std::endl;
}

void Debug::DumpHex(const void* data, size_t len) {
  const uint8_t* d = (const uint8_t*)data;
  for (size_t i = 0; i < len; i++) {
    std::cerr << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)d[i] << " ";
    if (i % 8 == 7) {
      std::cerr << "\n";
    }
  }

  if (len - 1 % 8 != 7) {
    std::cerr << std::endl;
  }
}

void Debug::DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer) {
  using namespace android;

  if (pool->getError() == NO_INIT) {
    printer->Print("String pool is unitialized.\n");
    return;
  } else if (pool->getError() != NO_ERROR) {
    printer->Print("String pool is corrupt/invalid.\n");
    return;
  }

  SortedVector<const void*> uniqueStrings;
  const size_t N = pool->size();
  for (size_t i=0; i<N; i++) {
    size_t len;
    if (pool->isUTF8()) {
      uniqueStrings.add(UnpackOptionalString(pool->string8At(i), &len));
    } else {
      uniqueStrings.add(UnpackOptionalString(pool->stringAt(i), &len));
    }
  }

  printer->Print(StringPrintf("String pool of %zd unique %s %s strings, %zd entries and %zd styles "
                              "using %zd bytes:\n", uniqueStrings.size(),
                              pool->isUTF8() ? "UTF-8" : "UTF-16",
                              pool->isSorted() ? "sorted" : "non-sorted", N, pool->styleCount(),
                              pool->bytes()));

  const size_t NS = pool->size();
  for (size_t s=0; s<NS; s++) {
    auto str = pool->string8ObjectAt(s);
    printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->string() : ""));
  }
}

namespace {

class XmlPrinter : public xml::ConstVisitor {
 public:
  using xml::ConstVisitor::Visit;

  explicit XmlPrinter(Printer* printer) : printer_(printer) {
  }

  void Visit(const xml::Element* el) override {
    for (const xml::NamespaceDecl& decl : el->namespace_decls) {
      printer_->Println(StringPrintf("N: %s=%s (line=%zu)", decl.prefix.c_str(), decl.uri.c_str(),
                                     decl.line_number));
      printer_->Indent();
    }

    printer_->Print("E: ");
    if (!el->namespace_uri.empty()) {
      printer_->Print(el->namespace_uri);
      printer_->Print(":");
    }
    printer_->Println(StringPrintf("%s (line=%zu)", el->name.c_str(), el->line_number));
    printer_->Indent();

    for (const xml::Attribute& attr : el->attributes) {
      printer_->Print("A: ");
      if (!attr.namespace_uri.empty()) {
        printer_->Print(attr.namespace_uri);
        printer_->Print(":");
      }
      printer_->Print(attr.name);

      if (attr.compiled_attribute) {
        printer_->Print("(");
        printer_->Print(attr.compiled_attribute.value().id.value_or(ResourceId(0)).to_string());
        printer_->Print(")");
      }
      printer_->Print("=");
      if (attr.compiled_value != nullptr) {
        attr.compiled_value->PrettyPrint(printer_);
      } else {
        printer_->Print("\"");
        printer_->Print(attr.value);
        printer_->Print("\"");
      }

      if (!attr.value.empty()) {
        printer_->Print(" (Raw: \"");
        printer_->Print(attr.value);
        printer_->Print("\")");
      }
      printer_->Println();
    }

    printer_->Indent();
    xml::ConstVisitor::Visit(el);
    printer_->Undent();
    printer_->Undent();

    for (size_t i = 0; i < el->namespace_decls.size(); i++) {
      printer_->Undent();
    }
  }

  void Visit(const xml::Text* text) override {
    printer_->Println(
        StringPrintf("T: '%s'", android::ResTable::normalizeForOutput(text->text.c_str()).c_str()));
  }

 private:
  Printer* printer_;
};

}  // namespace

void Debug::DumpXml(const xml::XmlResource& doc, Printer* printer) {
  XmlPrinter xml_visitor(printer);
  doc.root->Accept(&xml_visitor);
}

struct DumpOverlayableEntry {
  std::string overlayable_section;
  std::string policy_subsection;
  std::string resource_name;
};

void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer) {
  std::vector<DumpOverlayableEntry> items;
  for (const auto& package : table.packages) {
    for (const auto& type : package->types) {
      for (const auto& entry : type->entries) {
        if (entry->overlayable_item) {
          const auto& overlayable_item = entry->overlayable_item.value();
          const auto overlayable_section = StringPrintf(R"(name="%s" actor="%s")",
              overlayable_item.overlayable->name.c_str(),
              overlayable_item.overlayable->actor.c_str());
          const auto policy_subsection = StringPrintf(R"(policies="%s")",
              android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
          const auto value =
              StringPrintf("%s/%s", type->named_type.to_string().data(), entry->name.c_str());
          items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});
        }
      }
    }
  }

  std::sort(items.begin(), items.end(),
      [](const DumpOverlayableEntry& a, const DumpOverlayableEntry& b) {
        if (a.overlayable_section != b.overlayable_section) {
          return a.overlayable_section < b.overlayable_section;
        }
        if (a.policy_subsection != b.policy_subsection) {
          return a.policy_subsection < b.policy_subsection;
        }
        return a.resource_name < b.resource_name;
      });

  std::string last_overlayable_section;
  std::string last_policy_subsection;
  for (const auto& item : items) {
    if (last_overlayable_section != item.overlayable_section) {
      printer->Println(item.overlayable_section);
      last_overlayable_section = item.overlayable_section;
    }
    if (last_policy_subsection != item.policy_subsection) {
      printer->Indent();
      printer->Println(item.policy_subsection);
      last_policy_subsection = item.policy_subsection;
      printer->Undent();
    }
    printer->Indent();
    printer->Indent();
    printer->Println(item.resource_name);
    printer->Undent();
    printer->Undent();
  }
}

namespace {

using namespace android;

class ChunkPrinter {
 public:
  ChunkPrinter(const void* data, size_t len, Printer* printer, android::IDiagnostics* diag)
      : data_(data), data_len_(len), printer_(printer), diag_(diag) {
  }

  void PrintChunkHeader(const ResChunk_header* chunk) {
    switch (android::util::DeviceToHost16(chunk->type)) {
      case RES_STRING_POOL_TYPE:
        printer_->Print("[RES_STRING_POOL_TYPE]");
        break;
      case RES_TABLE_LIBRARY_TYPE:
        printer_->Print("[RES_TABLE_LIBRARY_TYPE]");
        break;
      case RES_TABLE_TYPE:
        printer_->Print("[ResTable_header]");
        break;
      case RES_TABLE_PACKAGE_TYPE:
        printer_->Print("[ResTable_package]");
        break;
      case RES_TABLE_TYPE_TYPE:
        printer_->Print("[ResTable_type]");
        break;
      case RES_TABLE_TYPE_SPEC_TYPE:
        printer_->Print("[RES_TABLE_TYPE_SPEC_TYPE]");
        break;
      default:
        break;
    }

    printer_->Print(StringPrintf(" chunkSize: %u", android::util::DeviceToHost32(chunk->size)));
    printer_->Print(
        StringPrintf(" headerSize: %u", android::util::DeviceToHost32(chunk->headerSize)));
  }

  bool PrintTable(const ResTable_header* chunk) {
    printer_->Print(
        StringPrintf(" Package count: %u\n", android::util::DeviceToHost32(chunk->packageCount)));

    // Print the chunks contained within the table
    printer_->Indent();
    bool success = PrintChunk(
        ResChunkPullParser(GetChunkData(&chunk->header), GetChunkDataLen(&chunk->header)));
    printer_->Undent();
    return success;
  }

  void PrintResValue(const Res_value* value, const ConfigDescription& config,
                     const ResourceType* type) {
    printer_->Print("[Res_value]");
    printer_->Print(StringPrintf(" size: %u", android::util::DeviceToHost32(value->size)));
    printer_->Print(
        StringPrintf(" dataType: 0x%02x", android::util::DeviceToHost32(value->dataType)));
    printer_->Print(StringPrintf(" data: 0x%08x", android::util::DeviceToHost32(value->data)));

    if (type) {
      auto item =
          ResourceUtils::ParseBinaryResValue(*type, config, value_pool_, *value, &out_pool_);
      printer_->Print(" (");
      item->PrettyPrint(printer_);
      printer_->Print(")");
    }

    printer_->Print("\n");
  }

  bool PrintTableType(const ResTable_type* chunk) {
    printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
    printer_->Print(StringPrintf(
        " name: %s",
        android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1)
            .c_str()));
    printer_->Print(StringPrintf(" flags: 0x%02x", android::util::DeviceToHost32(chunk->flags)));
    printer_->Print(
        StringPrintf(" entryCount: %u", android::util::DeviceToHost32(chunk->entryCount)));
    printer_->Print(
        StringPrintf(" entryStart: %u", android::util::DeviceToHost32(chunk->entriesStart)));

    ConfigDescription config;
    config.copyFromDtoH(chunk->config);
    printer_->Print(StringPrintf(" config: %s\n", config.to_string().c_str()));

    const ResourceType* type = ParseResourceType(
        android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1));

    printer_->Indent();

    TypeVariant tv(chunk);
    for (auto it = tv.beginEntries(); it != tv.endEntries(); ++it) {
      const ResTable_entry* entry = *it;
      if (!entry) {
        continue;
      }

      if (entry->is_complex()) {
        printer_->Print("[ResTable_map_entry]");
      } else if (entry->is_compact()) {
        printer_->Print("[ResTable_entry_compact]");
      } else {
        printer_->Print("[ResTable_entry]");
      }

      printer_->Print(StringPrintf(" id: 0x%04x", it.index()));
      printer_->Print(StringPrintf(
          " name: %s", android::util::GetString(key_pool_, entry->key()).c_str()));
      printer_->Print(StringPrintf(" keyIndex: %u", entry->key()));
      printer_->Print(StringPrintf(" size: %zu", entry->size()));
      printer_->Print(StringPrintf(" flags: 0x%04x", entry->flags()));

      printer_->Indent();

      if (auto map_entry = entry->map_entry()) {
        uint32_t map_entry_count = android::util::DeviceToHost32(map_entry->count);
        printer_->Print(StringPrintf(" count: 0x%04x", map_entry_count));
        printer_->Print(StringPrintf(" parent: 0x%08x\n",
                                     android::util::DeviceToHost32(map_entry->parent.ident)));

        // Print the name and value mappings
        auto maps = (const ResTable_map*)((const uint8_t*)entry + entry->size());
        for (size_t i = 0; i < map_entry_count; i++) {
          PrintResValue(&(maps[i].value), config, type);

          printer_->Print(StringPrintf(
              " name: %s name-id:%d\n",
              android::util::GetString(key_pool_, android::util::DeviceToHost32(maps[i].name.ident))
                  .c_str(),
              android::util::DeviceToHost32(maps[i].name.ident)));
        }
      } else {
        printer_->Print("\n");

        // Print the value of the entry
        Res_value value = entry->value();
        PrintResValue(&value, config, type);
      }

      printer_->Undent();
    }

    printer_->Undent();
    return true;
  }

  void PrintStringPool(const ResStringPool_header* chunk) {
    // Initialize the string pools

    ResStringPool* pool;
    if (value_pool_.getError() == NO_INIT) {
      pool = &value_pool_;
    } else if (type_pool_.getError() == NO_INIT) {
      pool = &type_pool_;
    } else if (key_pool_.getError() == NO_INIT) {
      pool = &key_pool_;
    } else {
      return;
    }

    pool->setTo(chunk, android::util::DeviceToHost32(
                           (reinterpret_cast<const ResChunk_header*>(chunk))->size));

    printer_->Print("\n");

    for (size_t i = 0; i < pool->size(); i++) {
      printer_->Print(StringPrintf("#%zd : %s\n", i, android::util::GetString(*pool, i).c_str()));
    }
  }

  bool PrintPackage(const ResTable_package* chunk) {
    printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));

    size_t len = strnlen16((const char16_t*)chunk->name, std::size(chunk->name));
    std::u16string package_name(len, u'\0');
    package_name.resize(len);
    for (size_t i = 0; i < len; i++) {
      package_name[i] = android::util::DeviceToHost16(chunk->name[i]);
    }

    printer_->Print(StringPrintf("name: %s", String8(package_name.c_str()).c_str()));
    printer_->Print(
        StringPrintf(" typeStrings: %u", android::util::DeviceToHost32(chunk->typeStrings)));
    printer_->Print(
        StringPrintf(" lastPublicType: %u", android::util::DeviceToHost32(chunk->lastPublicType)));
    printer_->Print(
        StringPrintf(" keyStrings: %u", android::util::DeviceToHost32(chunk->keyStrings)));
    printer_->Print(
        StringPrintf(" lastPublicKey: %u", android::util::DeviceToHost32(chunk->lastPublicKey)));
    printer_->Print(
        StringPrintf(" typeIdOffset: %u\n", android::util::DeviceToHost32(chunk->typeIdOffset)));

    // Print the chunks contained within the table
    printer_->Indent();
    bool success = PrintChunk(
        ResChunkPullParser(GetChunkData(&chunk->header), GetChunkDataLen(&chunk->header)));
    printer_->Undent();
    return success;
  }

  bool PrintChunk(ResChunkPullParser&& parser) {
    while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
      auto chunk = parser.chunk();
      PrintChunkHeader(chunk);

      switch (android::util::DeviceToHost16(chunk->type)) {
        case RES_STRING_POOL_TYPE:
          PrintStringPool(reinterpret_cast<const ResStringPool_header*>(chunk));
          break;

        case RES_TABLE_TYPE:
          PrintTable(reinterpret_cast<const ResTable_header*>(chunk));
          break;

        case RES_TABLE_PACKAGE_TYPE:
          type_pool_.uninit();
          key_pool_.uninit();
          PrintPackage(reinterpret_cast<const ResTable_package*>(chunk));
          break;

        case RES_TABLE_TYPE_TYPE:
          PrintTableType(reinterpret_cast<const ResTable_type*>(chunk));
          break;

        default:
          printer_->Print("\n");
          break;
      }
    }

    if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
      diag_->Error(android::DiagMessage(source_) << "corrupt resource table: " << parser.error());
      return false;
    }

    return true;
  }

  void Print() {
    PrintChunk(ResChunkPullParser(data_, data_len_));
    printer_->Print("[End]\n");
  }

 private:
  const android::Source source_;
  const void* data_;
  const size_t data_len_;
  Printer* printer_;
  android::IDiagnostics* diag_;

  // The standard value string pool for resource values.
  ResStringPool value_pool_;

  // The string pool that holds the names of the types defined
  // in this table.
  ResStringPool type_pool_;

  // The string pool that holds the names of the entries defined
  // in this table.
  ResStringPool key_pool_;

  android::StringPool out_pool_;
};

}  // namespace

void Debug::DumpChunks(const void* data, size_t len, Printer* printer,
                       android::IDiagnostics* diag) {
  ChunkPrinter chunk_printer(data, len, printer, diag);
  chunk_printer.Print();
}

}  // namespace aapt
