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

#include <dirent.h>

#include <string>

#include "ResourceParser.h"
#include "ResourceTable.h"
#include "android-base/errors.h"
#include "android-base/file.h"
#include "android-base/utf8.h"
#include "androidfw/BigBufferStream.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/FileStream.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/Image.h"
#include "androidfw/Png.h"
#include "androidfw/StringPiece.h"
#include "cmd/Util.h"
#include "compile/IdAssigner.h"
#include "compile/InlineXmlFormatParser.h"
#include "compile/PseudolocaleGenerator.h"
#include "compile/XmlIdCollector.h"
#include "format/Archive.h"
#include "format/Container.h"
#include "format/proto/ProtoSerialize.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "io/FileSystem.h"
#include "io/StringStream.h"
#include "io/Util.h"
#include "io/ZipArchive.h"
#include "process/ProductFilter.h"
#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "util/Util.h"
#include "xml/XmlDom.h"
#include "xml/XmlPullParser.h"

using ::aapt::text::Printer;
using ::android::ConfigDescription;
using ::android::FileInputStream;
using ::android::StringPiece;
using ::android::base::SystemErrorCodeToString;
using ::google::protobuf::io::CopyingOutputStreamAdaptor;

namespace aapt {

struct ResourcePathData {
  android::Source source;
  std::string resource_dir;
  std::string name;
  std::string extension;
  std::string flag_name;

  // Original config str. We keep this because when we parse the config, we may add on
  // version qualifiers. We want to preserve the original input so the output is easily
  // computed before hand.
  std::string config_str;
  ConfigDescription config;
};

// Resource file paths are expected to look like: [--/res/]type[-config]/name
static std::optional<ResourcePathData> ExtractResourcePathData(const std::string& path,
                                                               const char dir_sep,
                                                               std::string* out_error,
                                                               const CompileOptions& options) {
  std::vector<std::string> parts = util::Split(path, dir_sep);

  std::string flag_name;
  // Check for a flag
  for (auto iter = parts.begin(); iter != parts.end();) {
    if (iter->starts_with("flag(") && iter->ends_with(")")) {
      if (!flag_name.empty()) {
        if (out_error) *out_error = "resource path cannot contain more than one flag directory";
        return {};
      }
      flag_name = iter->substr(5, iter->size() - 6);
      iter = parts.erase(iter);
    } else {
      ++iter;
    }
  }

  if (parts.size() < 2) {
    if (out_error) *out_error = "bad resource path";
    return {};
  }

  std::string& dir = parts[parts.size() - 2];
  StringPiece dir_str = dir;

  StringPiece config_str;
  ConfigDescription config;
  size_t dash_pos = dir.find('-');
  if (dash_pos != std::string::npos) {
    config_str = dir_str.substr(dash_pos + 1, dir.size() - (dash_pos + 1));
    if (!ConfigDescription::Parse(config_str, &config)) {
      if (out_error) {
        std::stringstream err_str;
        err_str << "invalid configuration '" << config_str << "'";
        *out_error = err_str.str();
      }
      return {};
    }
    dir_str = dir_str.substr(0, dash_pos);
  }

  std::string& filename = parts[parts.size() - 1];
  StringPiece name = filename;
  StringPiece extension;

  const std::string kNinePng = ".9.png";
  if (filename.size() > kNinePng.size()
      && std::equal(kNinePng.rbegin(), kNinePng.rend(), filename.rbegin())) {
    // Split on .9.png if this extension is present at the end of the file path
    name = name.substr(0, filename.size() - kNinePng.size());
    extension = "9.png";
  } else {
    // Split on the last period occurrence
    size_t dot_pos = filename.rfind('.');
    if (dot_pos != std::string::npos) {
      extension = name.substr(dot_pos + 1, filename.size() - (dot_pos + 1));
      name = name.substr(0, dot_pos);
    }
  }

  const android::Source res_path =
      options.source_path ? StringPiece(options.source_path.value()) : StringPiece(path);

  return ResourcePathData{res_path,
                          std::string(dir_str),
                          std::string(name),
                          std::string(extension),
                          std::move(flag_name),
                          std::string(config_str),
                          config};
}

static std::string BuildIntermediateContainerFilename(const ResourcePathData& data) {
  std::stringstream name;
  name << data.resource_dir;
  if (!data.config_str.empty()) {
    name << "-" << data.config_str;
  }
  name << "_" << data.name;
  if (!data.flag_name.empty()) {
    name << ".(" << data.flag_name << ")";
  }
  if (!data.extension.empty()) {
    name << "." << data.extension;
  }
  name << ".flat";
  return name.str();
}

static bool CompileTable(IAaptContext* context, const CompileOptions& options,
                         const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
                         const std::string& output_path) {
  TRACE_CALL();
  // Filenames starting with "donottranslate" are not localizable
  bool translatable_file = path_data.name.find("donottranslate") != 0;
  ResourceTable table;
  {
    auto fin = file->OpenInputStream();
    if (fin->HadError()) {
      context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
                                       << "failed to open file: " << fin->GetError());
      return false;
    }
    // Parse the values file from XML.
    xml::XmlPullParser xml_parser(fin.get());

    ResourceParserOptions parser_options;
    parser_options.error_on_positional_arguments = !options.legacy_mode;
    parser_options.preserve_visibility_of_styleables = options.preserve_visibility_of_styleables;
    parser_options.translatable = translatable_file;
    parser_options.feature_flag_values = options.feature_flag_values;

    // If visibility was forced, we need to use it when creating a new resource and also error if
    // we try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags.
    parser_options.visibility = options.visibility;
    parser_options.flag = ParseFlag(path_data.flag_name);

    if (parser_options.flag) {
      std::string error;
      auto flag_status = GetFlagStatus(parser_options.flag, options.feature_flag_values, &error);
      if (flag_status) {
        parser_options.flag_status = std::move(flag_status.value());
      } else {
        context->GetDiagnostics()->Error(android::DiagMessage(path_data.source) << error);
        return false;
      }
    }

    ResourceParser res_parser(context->GetDiagnostics(), &table, path_data.source, path_data.config,
        parser_options);
    if (!res_parser.Parse(&xml_parser)) {
      return false;
    }

    if (options.product_.has_value()) {
      if (!ProductFilter({*options.product_}, /* remove_default_config_values = */ true)
               .Consume(context, &table)) {
        context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
                                         << "failed to filter product");
        return false;
      }
    }
  }

  if (options.pseudolocalize && translatable_file) {
    // Generate pseudo-localized strings (en-XA and ar-XB).
    // These are created as weak symbols, and are only generated from default
    // configuration
    // strings and plurals.
    std::string grammatical_gender_values;
    std::string grammatical_gender_ratio;
    if (options.pseudo_localize_gender_values) {
      grammatical_gender_values = options.pseudo_localize_gender_values.value();
    } else {
      grammatical_gender_values = "f,m,n";
    }
    if (options.pseudo_localize_gender_ratio) {
      grammatical_gender_ratio = options.pseudo_localize_gender_ratio.value();
    } else {
      grammatical_gender_ratio = "1.0";
    }
    PseudolocaleGenerator pseudolocale_generator(grammatical_gender_values,
                                                 grammatical_gender_ratio);
    if (!pseudolocale_generator.Consume(context, &table)) {
      return false;
    }
  }

  // Create the file/zip entry.
  if (!writer->StartEntry(output_path, 0)) {
    context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to open");
    return false;
  }

  // Make sure CopyingOutputStreamAdaptor is deleted before we call writer->FinishEntry().
  {
    // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    ContainerWriter container_writer(&copying_adaptor, 1u);

    pb::ResourceTable pb_table;
    SerializeTableToPb(table, &pb_table, context->GetDiagnostics());
    if (!container_writer.AddResTableEntry(pb_table)) {
      context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to write");
      return false;
    }
  }

  if (!writer->FinishEntry()) {
    context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to finish entry");
    return false;
  }

  if (options.generate_text_symbols_path) {
    android::FileOutputStream fout_text(options.generate_text_symbols_path.value());

    if (fout_text.HadError()) {
      context->GetDiagnostics()->Error(android::DiagMessage()
                                       << "failed writing to'"
                                       << options.generate_text_symbols_path.value()
                                       << "': " << fout_text.GetError());
      return false;
    }

    Printer r_txt_printer(&fout_text);
    for (const auto& package : table.packages) {
      // Only print resources defined locally, e.g. don't write android attributes.
      if (package->name.empty()) {
        for (const auto& type : package->types) {
          for (const auto& entry : type->entries) {
            // Check access modifiers.
            switch (entry->visibility.level) {
              case Visibility::Level::kUndefined :
                r_txt_printer.Print("default ");
                break;
              case Visibility::Level::kPublic :
                r_txt_printer.Print("public ");
                break;
              case Visibility::Level::kPrivate :
                r_txt_printer.Print("private ");
            }

            if (type->named_type.type != ResourceType::kStyleable) {
              r_txt_printer.Print("int ");
              r_txt_printer.Print(type->named_type.to_string());
              r_txt_printer.Print(" ");
              r_txt_printer.Println(entry->name);
            } else {
              r_txt_printer.Print("int[] styleable ");
              r_txt_printer.Println(entry->name);

              if (!entry->values.empty()) {
                auto styleable =
                    static_cast<const Styleable*>(entry->values.front()->value.get());
                for (const auto& attr : styleable->entries) {
                  // The visibility of the children under the styleable does not matter as they are
                  // nested under their parent and use its visibility.
                  r_txt_printer.Print("default int styleable ");
                  r_txt_printer.Print(entry->name);
                  // If the package name is present, also include it in the mangled name (e.g.
                  // "android")
                  if (!attr.name.value().package.empty()) {
                    r_txt_printer.Print("_");
                    r_txt_printer.Print(MakePackageSafeName(attr.name.value().package));
                  }
                  r_txt_printer.Print("_");
                  r_txt_printer.Println(attr.name.value().entry);
                }
              }
            }
          }
        }
      }
    }
  }

  return true;
}

static bool WriteHeaderAndDataToWriter(StringPiece output_path, const ResourceFile& file,
                                       android::KnownSizeInputStream* in, IArchiveWriter* writer,
                                       android::IDiagnostics* diag) {
  TRACE_CALL();
  // Start the entry so we can write the header.
  if (!writer->StartEntry(output_path, 0)) {
    diag->Error(android::DiagMessage(output_path) << "failed to open file");
    return false;
  }

  // Make sure CopyingOutputStreamAdaptor is deleted before we call writer->FinishEntry().
  {
    // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    ContainerWriter container_writer(&copying_adaptor, 1u);

    pb::internal::CompiledFile pb_compiled_file;
    SerializeCompiledFileToPb(file, &pb_compiled_file);

    if (!container_writer.AddResFileEntry(pb_compiled_file, in)) {
      diag->Error(android::DiagMessage(output_path) << "failed to write entry data");
      return false;
    }
  }

  if (!writer->FinishEntry()) {
    diag->Error(android::DiagMessage(output_path) << "failed to finish writing data");
    return false;
  }
  return true;
}

static bool FlattenXmlToOutStream(StringPiece output_path, const xml::XmlResource& xmlres,
                                  ContainerWriter* container_writer, android::IDiagnostics* diag) {
  pb::internal::CompiledFile pb_compiled_file;
  SerializeCompiledFileToPb(xmlres.file, &pb_compiled_file);

  pb::XmlNode pb_xml_node;
  SerializeXmlToPb(*xmlres.root, &pb_xml_node);

  std::string serialized_xml = pb_xml_node.SerializeAsString();
  io::StringInputStream serialized_in(serialized_xml);

  if (!container_writer->AddResFileEntry(pb_compiled_file, &serialized_in)) {
    diag->Error(android::DiagMessage(output_path) << "failed to write entry data");
    return false;
  }
  return true;
}

static bool IsValidFile(IAaptContext* context, const std::string& input_path) {
  const file::FileType file_type = file::GetFileType(input_path);
  if (file_type != file::FileType::kRegular && file_type != file::FileType::kSymlink) {
    if (file_type == file::FileType::kDirectory) {
      context->GetDiagnostics()->Error(android::DiagMessage(input_path)
                                       << "resource file cannot be a directory");
    } else if (file_type == file::FileType::kNonExistant) {
      context->GetDiagnostics()->Error(android::DiagMessage(input_path) << "file not found");
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage(input_path)
                                       << "not a valid resource file");
    }
    return false;
  }
  return true;
}

class FindReadWriteFlagsVisitor : public xml::Visitor {
 public:
  FindReadWriteFlagsVisitor(const FeatureFlagValues& feature_flag_values)
      : feature_flag_values_(feature_flag_values) {
  }

  void Visit(xml::Element* node) override {
    if (had_flags_) {
      return;
    }
    auto* attr = node->FindAttribute(xml::kSchemaAndroid, xml::kAttrFeatureFlag);
    if (attr != nullptr) {
      std::string_view flag_name = util::TrimWhitespace(attr->value);
      if (flag_name.starts_with('!')) {
        flag_name = flag_name.substr(1);
      }
      if (auto it = feature_flag_values_.find(flag_name); it != feature_flag_values_.end()) {
        if (!it->second.read_only) {
          had_flags_ = true;
          return;
        }
      } else {
        // Flag not passed to aapt2, must evaluate at runtime
        had_flags_ = true;
        return;
      }
    }
    VisitChildren(node);
  }

  bool HadFlags() const {
    return had_flags_;
  }

 private:
  bool had_flags_ = false;
  const FeatureFlagValues& feature_flag_values_;
};

static bool CompileXml(IAaptContext* context, const CompileOptions& options,
                       const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
                       const std::string& output_path) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling XML");
  }

  std::unique_ptr<xml::XmlResource> xmlres;
  {
    auto fin = file->OpenInputStream();
    if (fin->HadError()) {
      context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
                                       << "failed to open file: " << fin->GetError());
      return false;
    }

    xmlres = xml::Inflate(fin.get(), context->GetDiagnostics(), path_data.source);
    if (!xmlres) {
      return false;
    }
  }

  xmlres->file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
  xmlres->file.config = path_data.config;
  xmlres->file.source = path_data.source;
  xmlres->file.type = ResourceFile::Type::kProtoXml;
  xmlres->file.flag = ParseFlag(path_data.flag_name);

  FindReadWriteFlagsVisitor visitor(options.feature_flag_values);
  xmlres->root->Accept(&visitor);
  xmlres->file.uses_readwrite_feature_flags = visitor.HadFlags();

  if (xmlres->file.flag) {
    std::string error;
    auto flag_status = GetFlagStatus(xmlres->file.flag, options.feature_flag_values, &error);
    if (flag_status) {
      xmlres->file.flag_status = flag_status.value();
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage(path_data.source) << error);
      return false;
    }
  }

  // Collect IDs that are defined here.
  XmlIdCollector collector;
  if (!collector.Consume(context, xmlres.get())) {
    return false;
  }

  // Look for and process any <aapt:attr> tags and create sub-documents.
  InlineXmlFormatParser inline_xml_format_parser;
  if (!inline_xml_format_parser.Consume(context, xmlres.get())) {
    return false;
  }

  // Start the entry so we can write the header.
  if (!writer->StartEntry(output_path, 0)) {
    context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to open file");
    return false;
  }

  std::vector<std::unique_ptr<xml::XmlResource>>& inline_documents =
      inline_xml_format_parser.GetExtractedInlineXmlDocuments();

  // Make sure CopyingOutputStreamAdaptor is deleted before we call writer->FinishEntry().
  {
    // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    ContainerWriter container_writer(&copying_adaptor, 1u + inline_documents.size());

    if (!FlattenXmlToOutStream(output_path, *xmlres, &container_writer,
                               context->GetDiagnostics())) {
      return false;
    }

    for (const std::unique_ptr<xml::XmlResource>& inline_xml_doc : inline_documents) {
      if (!FlattenXmlToOutStream(output_path, *inline_xml_doc, &container_writer,
                                 context->GetDiagnostics())) {
        return false;
      }
    }
  }

  if (!writer->FinishEntry()) {
    context->GetDiagnostics()->Error(android::DiagMessage(output_path)
                                     << "failed to finish writing data");
    return false;
  }

  if (options.generate_text_symbols_path) {
    android::FileOutputStream fout_text(options.generate_text_symbols_path.value());

    if (fout_text.HadError()) {
      context->GetDiagnostics()->Error(android::DiagMessage()
                                       << "failed writing to'"
                                       << options.generate_text_symbols_path.value()
                                       << "': " << fout_text.GetError());
      return false;
    }

    Printer r_txt_printer(&fout_text);
    for (const auto& res : xmlres->file.exported_symbols) {
      r_txt_printer.Print("default int id ");
      r_txt_printer.Println(res.name.entry);
    }

    // And print ourselves.
    r_txt_printer.Print("default int ");
    r_txt_printer.Print(path_data.resource_dir);
    r_txt_printer.Print(" ");
    r_txt_printer.Println(path_data.name);
  }

  return true;
}

static bool CompilePng(IAaptContext* context, const CompileOptions& options,
                       const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
                       const std::string& output_path) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling PNG");
  }

  android::BigBuffer buffer(4096);
  ResourceFile res_file;
  res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
  res_file.config = path_data.config;
  res_file.source = path_data.source;
  res_file.type = ResourceFile::Type::kPng;

  if (!path_data.flag_name.empty()) {
    FeatureFlagAttribute flag;
    auto name = path_data.flag_name;
    if (name.starts_with('!')) {
      flag.negated = true;
      flag.name = name.substr(1);
    } else {
      flag.name = name;
    }
    res_file.flag = flag;

    std::string error;
    auto flag_status = GetFlagStatus(flag, options.feature_flag_values, &error);
    if (flag_status) {
      res_file.flag_status = flag_status.value();
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage(path_data.source) << error);
      return false;
    }
  }

  {
    auto data = file->OpenAsData();
    if (!data) {
      context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
                                       << "failed to open file ");
      return false;
    }

    android::BigBuffer crunched_png_buffer(4096);
    android::BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);

    // Ensure that we only keep the chunks we care about if we end up
    // using the original PNG instead of the crunched one.
    const StringPiece content(reinterpret_cast<const char*>(data->data()), data->size());
    android::PngChunkFilter png_chunk_filter(content);
    android::SourcePathDiagnostics source_diag(path_data.source, context->GetDiagnostics());
    auto image = android::ReadPng(&png_chunk_filter, &source_diag);
    if (!image) {
      return false;
    }

    std::unique_ptr<android::NinePatch> nine_patch;
    if (path_data.extension == "9.png") {
      std::string err;
      nine_patch = android::NinePatch::Create(image->rows.get(), image->width, image->height, &err);
      if (!nine_patch) {
        context->GetDiagnostics()->Error(android::DiagMessage() << err);
        return false;
      }

      // Remove the 1px border around the NinePatch.
      // Basically the row array is shifted up by 1, and the length is treated
      // as height - 2.
      // For each row, shift the array to the left by 1, and treat the length as
      // width - 2.
      image->width -= 2;
      image->height -= 2;
      memmove(image->rows.get(), image->rows.get() + 1, image->height * sizeof(uint8_t**));
      for (int32_t h = 0; h < image->height; h++) {
        memmove(image->rows[h], image->rows[h] + 4, image->width * 4);
      }

      if (context->IsVerbose()) {
        context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
                                        << "9-patch: " << *nine_patch);
      }
    }

    // Write the crunched PNG.
    if (!android::WritePng(image.get(), nine_patch.get(), &crunched_png_buffer_out,
                           {.compression_level = options.png_compression_level_int}, &source_diag,
                           context->IsVerbose())) {
      return false;
    }

    if (nine_patch != nullptr ||
        crunched_png_buffer_out.ByteCount() <= png_chunk_filter.ByteCount()) {
      // No matter what, we must use the re-encoded PNG, even if it is larger.
      // 9-patch images must be re-encoded since their borders are stripped.
      buffer.AppendBuffer(std::move(crunched_png_buffer));
    } else {
      // The re-encoded PNG is larger than the original, and there is
      // no mandatory transformation. Use the original.
      if (context->IsVerbose()) {
        context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
                                        << "original PNG is smaller than crunched PNG"
                                        << ", using original");
      }

      png_chunk_filter.Rewind();
      android::BigBuffer filtered_png_buffer(4096);
      android::BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer);
      io::Copy(&filtered_png_buffer_out, &png_chunk_filter);
      buffer.AppendBuffer(std::move(filtered_png_buffer));
    }

    if (context->IsVerbose()) {
      // For debugging only, use the legacy PNG cruncher and compare the resulting file sizes.
      // This will help catch exotic cases where the new code may generate larger PNGs.
      std::stringstream legacy_stream{std::string(content)};
      android::BigBuffer legacy_buffer(4096);
      android::Png png(context->GetDiagnostics());
      if (!png.process(path_data.source, &legacy_stream, &legacy_buffer, {})) {
        return false;
      }

      context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
                                      << "legacy=" << legacy_buffer.size()
                                      << " new=" << buffer.size());
    }
  }

  android::BigBufferInputStream buffer_in(&buffer);
  return WriteHeaderAndDataToWriter(output_path, res_file, &buffer_in, writer,
      context->GetDiagnostics());
}

static bool CompileFile(IAaptContext* context, const CompileOptions& options,
                        const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
                        const std::string& output_path) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling file");
  }

  ResourceFile res_file;
  res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
  res_file.config = path_data.config;
  res_file.source = path_data.source;
  res_file.type = ResourceFile::Type::kUnknown;

  auto data = file->OpenAsData();
  if (!data) {
    context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
                                     << "failed to open file ");
    return false;
  }

  return WriteHeaderAndDataToWriter(output_path, res_file, data.get(), writer,
      context->GetDiagnostics());
}

class CompileContext : public IAaptContext {
 public:
  explicit CompileContext(android::IDiagnostics* diagnostics) : diagnostics_(diagnostics) {
  }

  PackageType GetPackageType() override {
    // Every compilation unit starts as an app and then gets linked as potentially something else.
    return PackageType::kApp;
  }

  void SetVerbose(bool val) {
    verbose_ = val;
    diagnostics_->SetVerbose(val);
  }

  bool IsVerbose() override {
    return verbose_;
  }

  android::IDiagnostics* GetDiagnostics() override {
    return diagnostics_;
  }

  NameMangler* GetNameMangler() override {
    UNIMPLEMENTED(FATAL) << "No name mangling should be needed in compile phase";
    return nullptr;
  }

  const std::string& GetCompilationPackage() override {
    static std::string empty;
    return empty;
  }

  uint8_t GetPackageId() override {
    return 0x0;
  }

  SymbolTable* GetExternalSymbols() override {
    UNIMPLEMENTED(FATAL) << "No symbols should be needed in compile phase";
    return nullptr;
  }

  int GetMinSdkVersion() override {
    return 0;
  }

  const std::set<std::string>& GetSplitNameDependencies() override {
    UNIMPLEMENTED(FATAL) << "No Split Name Dependencies be needed in compile phase";
    static std::set<std::string> empty;
    return empty;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CompileContext);

  android::IDiagnostics* diagnostics_;
  bool verbose_ = false;
};

int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
             CompileOptions& options) {
  TRACE_CALL();
  bool error = false;

  // Iterate over the input files in a stable, platform-independent manner
  auto file_iterator  = inputs->Iterator();
  while (file_iterator->HasNext()) {
    auto file = file_iterator->Next();
    const std::string& path = file->GetSource().path;

    // Skip hidden input files
    if (file::IsHidden(path)) {
      continue;
    }

    if (!options.res_zip && !IsValidFile(context, path)) {
      error = true;
      continue;
    }

    // Extract resource type information from the full path
    std::string err_str;
    ResourcePathData path_data;
    if (auto maybe_path_data = ExtractResourcePathData(
        path, inputs->GetDirSeparator(), &err_str, options)) {
      path_data = std::move(maybe_path_data.value());
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource()) << err_str);
      error = true;
      continue;
    }

    if (path_data.config.minorVersion != 0 && path_data.config.sdkVersion < SDK_BAKLAVA) {
      context->GetDiagnostics()->Error(
          android::DiagMessage(file->GetSource())
          << "SDK version in '" << path_data.config
          << "' is not valid: minor versions are only available since v" << SDK_BAKLAVA);
      error = true;
      continue;
    }

    // Determine how to compile the file based on its type.
    auto compile_func = &CompileFile;
    if (path_data.resource_dir == "values" && path_data.extension == "xml") {
      compile_func = &CompileTable;
      // We use a different extension (not necessary anymore, but avoids altering the existing
      // build system logic).
      path_data.extension = "arsc";
    } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) {
      if (*type != ResourceType::kRaw) {
        if (*type == ResourceType::kXml || path_data.extension == "xml") {
          compile_func = &CompileXml;
        } else if ((!options.no_png_crunch && path_data.extension == "png")
                   || path_data.extension == "9.png") {
          compile_func = &CompilePng;
        }
      }
    } else {
      context->GetDiagnostics()->Error(android::DiagMessage()
                                       << "invalid file path '" << path_data.source << "'");
      error = true;
      continue;
    }

    // Treat periods as a reserved character that should not be present in a file name
    // Legacy support for AAPT which did not reserve periods
    if (compile_func != &CompileFile && !options.legacy_mode && path_data.name.contains('.')) {
      error = true;
      context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                       << "file name cannot contain '.' other than for"
                                       << " specifying the extension");
      continue;
    }

    const std::string out_path = BuildIntermediateContainerFilename(path_data);
    if (!compile_func(context, options, path_data, file, output_writer, out_path)) {
      context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                       << "file failed to compile");
      error = true;
    }
  }

  return error ? 1 : 0;
}

int CompileCommand::Action(const std::vector<std::string>& args) {
  TRACE_FLUSH(trace_folder_? trace_folder_.value() : "", "CompileCommand::Action");
  CompileContext context(diagnostic_);
  context.SetVerbose(options_.verbose);

  if (visibility_) {
    if (visibility_.value() == "public") {
      options_.visibility = Visibility::Level::kPublic;
    } else if (visibility_.value() == "private") {
      options_.visibility = Visibility::Level::kPrivate;
    } else if (visibility_.value() == "default") {
      options_.visibility = Visibility::Level::kUndefined;
    } else {
      context.GetDiagnostics()->Error(android::DiagMessage()
                                      << "Unrecognized visibility level passes to --visibility: '"
                                      << visibility_.value()
                                      << "'. Accepted levels: public, private, default");
      return 1;
    }
  }

  std::unique_ptr<io::IFileCollection> file_collection;

  // Collect the resources files to compile
  if (options_.res_dir && options_.res_zip) {
    context.GetDiagnostics()->Error(android::DiagMessage()
                                    << "only one of --dir and --zip can be specified");
    return 1;
  } else if ((options_.res_dir || options_.res_zip) &&
              options_.source_path && args.size() > 1) {
    context.GetDiagnostics()->Error(android::DiagMessage(kPath)
                                    << "Cannot use an overriding source path with multiple files.");
    return 1;
  } else if (options_.res_dir) {
    if (!args.empty()) {
      context.GetDiagnostics()->Error(android::DiagMessage() << "files given but --dir specified");
      Usage(&std::cerr);
      return 1;
    }

    // Load the files from the res directory
    std::string err;
    file_collection = io::FileCollection::Create(options_.res_dir.value(), &err);
    if (!file_collection) {
      context.GetDiagnostics()->Error(android::DiagMessage(options_.res_dir.value()) << err);
      return 1;
    }
  } else if (options_.res_zip) {
    if (!args.empty()) {
      context.GetDiagnostics()->Error(android::DiagMessage() << "files given but --zip specified");
      Usage(&std::cerr);
      return 1;
    }

    // Load a zip file containing a res directory
    std::string err;
    file_collection = io::ZipFileCollection::Create(options_.res_zip.value(), &err);
    if (!file_collection) {
      context.GetDiagnostics()->Error(android::DiagMessage(options_.res_zip.value()) << err);
      return 1;
    }
  } else {
    auto collection = util::make_unique<io::FileCollection>();

    // Collect data from the path for each input file.
    std::vector<std::string> sorted_args = args;
    std::sort(sorted_args.begin(), sorted_args.end());

    for (const std::string& arg : sorted_args) {
      collection->InsertFile(arg);
    }

    file_collection = std::move(collection);
  }

  std::unique_ptr<IArchiveWriter> archive_writer;
  file::FileType output_file_type = file::GetFileType(options_.output_path);
  if (output_file_type == file::FileType::kDirectory) {
    archive_writer = CreateDirectoryArchiveWriter(context.GetDiagnostics(), options_.output_path);
  } else {
    archive_writer = CreateZipFileArchiveWriter(context.GetDiagnostics(), options_.output_path);
  }

  if (!archive_writer) {
    return 1;
  }

  // Parse the feature flag values. An argument that starts with '@' points to a file to read flag
  // values from.
  std::vector<std::string> all_feature_flags_args;
  for (const std::string& arg : feature_flags_args_) {
    if (util::StartsWith(arg, "@")) {
      const std::string path = arg.substr(1, arg.size() - 1);
      std::string error;
      if (!file::AppendArgsFromFile(path, &all_feature_flags_args, &error)) {
        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
        return 1;
      }
    } else {
      all_feature_flags_args.push_back(arg);
    }
  }

  for (const std::string& arg : all_feature_flags_args) {
    if (!ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) {
      return 1;
    }
  }

  if (!options_.png_compression_level) {
    options_.png_compression_level_int = 9;
  } else {
    if (options_.png_compression_level->size() != 1 ||
        options_.png_compression_level->front() < '0' ||
        options_.png_compression_level->front() > '9') {
      context.GetDiagnostics()->Error(
          android::DiagMessage() << "PNG compression level should be a number in [0..9] range");
      return 1;
    }
    options_.png_compression_level_int = options_.png_compression_level->front() - '0';
  }

  return Compile(&context, file_collection.get(), archive_writer.get(), options_);
}

}  // namespace aapt
