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

#include <unordered_set>

#include "ResourceUtils.h"
#include "android-base/logging.h"
#include "process/SymbolTable.h"
#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlActionExecutor.h"
#include "xml/XmlDom.h"

using android::StringPiece;

namespace aapt {

// This is to detect whether an <intent-filter> contains deeplink.
// See https://developer.android.com/training/app-links/deep-linking.
static bool HasDeepLink(xml::Element* intent_filter_el) {
  xml::Element* action_el = intent_filter_el->FindChild({}, "action");
  xml::Element* category_el = intent_filter_el->FindChild({}, "category");
  xml::Element* data_el = intent_filter_el->FindChild({}, "data");
  if (action_el == nullptr || category_el == nullptr || data_el == nullptr) {
    return false;
  }

  // Deeplinks must specify the ACTION_VIEW intent action.
  constexpr const char* action_view = "android.intent.action.VIEW";
  if (intent_filter_el->FindChildWithAttribute({}, "action", xml::kSchemaAndroid, "name",
                                               action_view) == nullptr) {
    return false;
  }

  // Deeplinks must have scheme included in <data> tag.
  xml::Attribute* data_scheme_attr = data_el->FindAttribute(xml::kSchemaAndroid, "scheme");
  if (data_scheme_attr == nullptr || data_scheme_attr->value.empty()) {
    return false;
  }

  // Deeplinks must include BROWSABLE category.
  constexpr const char* category_browsable = "android.intent.category.BROWSABLE";
  if (intent_filter_el->FindChildWithAttribute({}, "category", xml::kSchemaAndroid, "name",
                                               category_browsable) == nullptr) {
    return false;
  }
  return true;
}

static bool VerifyDeeplinkPathAttribute(xml::Element* data_el, android::SourcePathDiagnostics* diag,
                                        const std::string& attr_name) {
  xml::Attribute* attr = data_el->FindAttribute(xml::kSchemaAndroid, attr_name);
  if (attr != nullptr && !attr->value.empty()) {
    StringPiece attr_value = attr->value;
    const char* startChar = attr_value.begin();
    if (attr_name == "pathPattern") {
      // pathPattern starts with '.' or '*' does not need leading slash.
      // Reference starts with @ does not need leading slash.
      if (*startChar == '/' || *startChar == '.' || *startChar == '*' || *startChar == '@') {
        return true;
      } else {
        diag->Error(android::DiagMessage(data_el->line_number)
                    << "attribute 'android:" << attr_name << "' in <" << data_el->name
                    << "> tag has value of '" << attr_value
                    << "', it must be in a pattern start with '.' or '*', otherwise must start "
                       "with a leading slash '/'");
        return false;
      }
    } else {
      // Reference starts with @ does not need leading slash.
      if (*startChar == '/' || *startChar == '@') {
        return true;
      } else {
        diag->Error(android::DiagMessage(data_el->line_number)
                    << "attribute 'android:" << attr_name << "' in <" << data_el->name
                    << "> tag has value of '" << attr_value
                    << "', it must start with a leading slash '/'");
        return false;
      }
    }
  }
  return true;
}

static bool VerifyDeepLinkIntentAction(xml::Element* intent_filter_el,
                                       android::SourcePathDiagnostics* diag) {
  if (!HasDeepLink(intent_filter_el)) {
    return true;
  }

  xml::Element* data_el = intent_filter_el->FindChild({}, "data");
  if (data_el != nullptr) {
    if (!VerifyDeeplinkPathAttribute(data_el, diag, "path")) {
      return false;
    }
    if (!VerifyDeeplinkPathAttribute(data_el, diag, "pathPrefix")) {
      return false;
    }
    if (!VerifyDeeplinkPathAttribute(data_el, diag, "pathPattern")) {
      return false;
    }
  }
  return true;
}

static bool RequiredNameIsNotEmpty(xml::Element* el, android::SourcePathDiagnostics* diag) {
  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
  if (attr == nullptr) {
    diag->Error(android::DiagMessage(el->line_number)
                << "<" << el->name << "> is missing attribute 'android:name'");
    return false;
  }

  if (attr->value.empty()) {
    diag->Error(android::DiagMessage(el->line_number)
                << "attribute 'android:name' in <" << el->name << "> tag must not be empty");
    return false;
  }
  return true;
}

// This is how PackageManager builds class names from AndroidManifest.xml entries.
static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
                                android::SourcePathDiagnostics* diag) {
  // We allow unqualified class names (ie: .HelloActivity)
  // Since we don't know the package name, we can just make a fake one here and
  // the test will be identical as long as the real package name is valid too.
  std::optional<std::string> fully_qualified_class_name =
      util::GetFullyQualifiedClassName("a", attr->value);

  StringPiece qualified_class_name = fully_qualified_class_name
                                         ? fully_qualified_class_name.value()
                                         : attr->value;

  if (!util::IsJavaClassName(qualified_class_name)) {
    diag->Error(android::DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name
                                                      << "> tag must be a valid Java class name");
    return false;
  }
  return true;
}

static bool OptionalNameIsJavaClassName(xml::Element* el, android::SourcePathDiagnostics* diag) {
  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
    return NameIsJavaClassName(el, attr, diag);
  }
  return true;
}

static bool RequiredNameIsJavaClassName(xml::Element* el, android::SourcePathDiagnostics* diag) {
  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
  if (attr == nullptr) {
    diag->Error(android::DiagMessage(el->line_number)
                << "<" << el->name << "> is missing attribute 'android:name'");
    return false;
  }
  return NameIsJavaClassName(el, attr, diag);
}

static bool UpdateConfigChangesIfNeeded(xml::Element* el, IAaptContext* context) {
  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "configChanges");
  if (attr == nullptr) {
    return true;
  }

  if (attr->value != "allKnown" && attr->value.find("allKnown") != std::string::npos) {
    context->GetDiagnostics()->Error(
        android::DiagMessage(el->line_number)
        << "If you want to declare 'allKnown' in attribute 'android:configChanges' in <" << el->name
        << ">, " << attr->value << " is not allowed', allKnown has to be used "
        << "by itself, for example: 'android:configChanges=allKnown', it cannot be combined with "
        << "the other flags");
    return false;
  }

  if (attr->value == "allKnown") {
    SymbolTable* symbol_table = context->GetExternalSymbols();
    const SymbolTable::Symbol* symbol =
        symbol_table->FindByName(ResourceName("android", ResourceType::kAttr, "configChanges"));

    if (symbol == nullptr) {
      context->GetDiagnostics()->Error(
          android::DiagMessage(el->line_number)
          << "Cannot find symbol for android:configChanges with min sdk: "
          << context->GetMinSdkVersion());
      return false;
    }

    std::stringstream new_value;

    const auto& symbols = symbol->attribute->symbols;
    for (auto it = symbols.begin(); it != symbols.end(); ++it) {
      // Skip 'resourcesUnused' which is the flag to fully disable activity restart specifically
      // for games.
      if (it->symbol.name.value().entry == "resourcesUnused") {
        continue;
      }
      if (it != symbols.begin()) {
        new_value << "|";
      }
      new_value << it->symbol.name.value().entry;
    }
    const auto& old_value = attr->value;
    auto new_value_str = new_value.str();
    context->GetDiagnostics()->Note(android::DiagMessage(el->line_number)
                                    << "Updating value of 'android:configChanges' from "
                                    << old_value << " to " << new_value_str);
    attr->value = std::move(new_value_str);
  }
  return true;
}

static bool RequiredNameIsJavaPackage(xml::Element* el, android::SourcePathDiagnostics* diag) {
  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
  if (attr == nullptr) {
    diag->Error(android::DiagMessage(el->line_number)
                << "<" << el->name << "> is missing attribute 'android:name'");
    return false;
  }

  if (!util::IsJavaPackageName(attr->value)) {
    diag->Error(android::DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name
                                                      << "> tag must be a valid Java package name");
    return false;
  }
  return true;
}

static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) {
  return [=](xml::Element* el, android::SourcePathDiagnostics* diag) -> bool {
    if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "<" << el->name << "> is missing required attribute 'android:" << attr << "'");
      return false;
    }
    return true;
  };
}

static xml::XmlNodeAction::ActionFuncWithDiag RequiredOneAndroidAttribute(
    const std::string& attrName1, const std::string& attrName2) {
  return [=](xml::Element* el, android::SourcePathDiagnostics* diag) -> bool {
    xml::Attribute* attr1 = el->FindAttribute(xml::kSchemaAndroid, attrName1);
    xml::Attribute* attr2 = el->FindAttribute(xml::kSchemaAndroid, attrName2);
    if (attr1 == nullptr && attr2 == nullptr) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "<" << el->name << "> is missing required attribute 'android:" << attrName1
                  << "' or 'android:" << attrName2 << "'");
      return false;
    }
    if (attr1 != nullptr && attr2 != nullptr) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "<" << el->name << "> can only specify one of attribute 'android:" << attrName1
                  << "' or 'android:" << attrName2 << "'");
      return false;
    }
    return true;
  };
}

static bool AutoGenerateIsFeatureSplit(xml::Element* el, android::SourcePathDiagnostics* diag) {
  constexpr const char* kFeatureSplit = "featureSplit";
  constexpr const char* kIsFeatureSplit = "isFeatureSplit";

  xml::Attribute* attr = el->FindAttribute({}, kFeatureSplit);
  if (attr != nullptr) {
    // Rewrite the featureSplit attribute to be "split". This is what the
    // platform recognizes.
    attr->name = "split";

    // Now inject the android:isFeatureSplit="true" attribute.
    xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, kIsFeatureSplit);
    if (attr != nullptr) {
      if (!ResourceUtils::ParseBool(attr->value).value_or(false)) {
        // The isFeatureSplit attribute is false, which conflicts with the use
        // of "featureSplit".
        diag->Error(android::DiagMessage(el->line_number)
                    << "attribute 'featureSplit' used in <manifest> but 'android:isFeatureSplit' "
                       "is not 'true'");
        return false;
      }

      // The attribute is already there and set to true, nothing to do.
    } else {
      el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, kIsFeatureSplit, "true"});
    }
  }
  return true;
}

static bool AutoGenerateIsSplitRequired(xml::Element* el, android::SourcePathDiagnostics* diag) {
  constexpr const char* kRequiredSplitTypes = "requiredSplitTypes";
  constexpr const char* kIsSplitRequired = "isSplitRequired";

  xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, kRequiredSplitTypes);
  if (attr != nullptr) {
    // Now inject the android:isSplitRequired="true" attribute.
    xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, kIsSplitRequired);
    if (attr != nullptr) {
      if (!ResourceUtils::ParseBool(attr->value).value_or(false)) {
        // The isFeatureSplit attribute is false, which conflicts with the use
        // of "featureSplit".
        diag->Error(android::DiagMessage(el->line_number)
                    << "attribute 'requiredSplitTypes' used in <manifest> but "
                       "'android:isSplitRequired' is not 'true'");
        return false;
      }
      // The attribute is already there and set to true, nothing to do.
    } else {
      el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, kIsSplitRequired, "true"});
    }
  }
  return true;
}

static bool VerifyManifest(xml::Element* el, xml::XmlActionExecutorPolicy policy,
                           android::SourcePathDiagnostics* diag) {
  xml::Attribute* attr = el->FindAttribute({}, "package");
  if (!attr) {
    diag->Error(android::DiagMessage(el->line_number)
                << "<manifest> tag is missing 'package' attribute");
    return false;
  } else if (ResourceUtils::IsReference(attr->value)) {
    diag->Error(android::DiagMessage(el->line_number)
                << "attribute 'package' in <manifest> tag must not be a reference");
    return false;
  } else if (!util::IsAndroidPackageName(attr->value)) {
    android::DiagMessage error_msg(el->line_number);
    error_msg << "attribute 'package' in <manifest> tag is not a valid Android package name: '"
              << attr->value << "'";
    if (policy == xml::XmlActionExecutorPolicy::kAllowListWarning) {
      // Treat the error only as a warning.
      diag->Warn(error_msg);
    } else {
      diag->Error(error_msg);
      return false;
    }
  }

  attr = el->FindAttribute({}, "split");
  if (attr) {
    if (!util::IsJavaPackageName(attr->value)) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "attribute 'split' in <manifest> tag is not a "
                     "valid split name");
      return false;
    }
  }
  return true;
}

// The coreApp attribute in <manifest> is not a regular AAPT attribute, so type
// checking on it is manual.
static bool FixCoreAppAttribute(xml::Element* el, android::SourcePathDiagnostics* diag) {
  if (xml::Attribute* attr = el->FindAttribute("", "coreApp")) {
    std::unique_ptr<BinaryPrimitive> result = ResourceUtils::TryParseBool(attr->value);
    if (!result) {
      diag->Error(android::DiagMessage(el->line_number) << "attribute coreApp must be a boolean");
      return false;
    }
    attr->compiled_value = std::move(result);
  }
  return true;
}

// Checks that <uses-feature> has android:glEsVersion or android:name, not both (or neither).
static bool VerifyUsesFeature(xml::Element* el, android::SourcePathDiagnostics* diag) {
  bool has_name = false;
  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
    if (attr->value.empty()) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "android:name in <uses-feature> must not be empty");
      return false;
    }
    has_name = true;
  }

  bool has_gl_es_version = false;
  if (el->FindAttribute(xml::kSchemaAndroid, "glEsVersion")) {
    if (has_name) {
      diag->Error(android::DiagMessage(el->line_number)
                  << "cannot define both android:name and android:glEsVersion in <uses-feature>");
      return false;
    }
    has_gl_es_version = true;
  }

  if (!has_name && !has_gl_es_version) {
    diag->Error(android::DiagMessage(el->line_number)
                << "<uses-feature> must have either android:name or android:glEsVersion attribute");
    return false;
  }
  return true;
}

// Ensure that 'ns_decls' contains a declaration for 'uri', using 'prefix' as
// the xmlns prefix if possible.
static void EnsureNamespaceIsDeclared(const std::string& prefix, const std::string& uri,
                                      std::vector<xml::NamespaceDecl>* ns_decls) {
  if (std::find_if(ns_decls->begin(), ns_decls->end(), [&](const xml::NamespaceDecl& ns_decl) {
        return ns_decl.uri == uri;
      }) != ns_decls->end()) {
    return;
  }

  std::set<std::string> used_prefixes;
  for (const auto& ns_decl : *ns_decls) {
    used_prefixes.insert(ns_decl.prefix);
  }

  // Make multiple attempts in the unlikely event that 'prefix' is already taken.
  std::string disambiguator;
  for (int i = 0; i < used_prefixes.size() + 1; i++) {
    std::string attempted_prefix = prefix + disambiguator;
    if (used_prefixes.find(attempted_prefix) == used_prefixes.end()) {
      ns_decls->push_back(xml::NamespaceDecl{attempted_prefix, uri});
      return;
    }
    disambiguator = std::to_string(i);
  }
}

bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, IAaptContext* context) {
  // First verify some options.
  android::IDiagnostics* diag = context->GetDiagnostics();
  if (options_.rename_manifest_package) {
    if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) {
      diag->Error(android::DiagMessage() << "invalid manifest package override '"
                                         << options_.rename_manifest_package.value() << "'");
      return false;
    }
  }

  if (options_.rename_instrumentation_target_package) {
    if (!util::IsJavaPackageName(options_.rename_instrumentation_target_package.value())) {
      diag->Error(android::DiagMessage()
                  << "invalid instrumentation target package override '"
                  << options_.rename_instrumentation_target_package.value() << "'");
      return false;
    }
  }

  if (options_.rename_overlay_target_package) {
    if (!util::IsJavaPackageName(options_.rename_overlay_target_package.value())) {
      diag->Error(android::DiagMessage() << "invalid overlay target package override '"
                                         << options_.rename_overlay_target_package.value() << "'");
      return false;
    }
  }

  // Common <intent-filter> actions.
  xml::XmlNodeAction intent_filter_action;
  intent_filter_action.Action(VerifyDeepLinkIntentAction);
  intent_filter_action["action"].Action(RequiredNameIsNotEmpty);
  intent_filter_action["category"].Action(RequiredNameIsNotEmpty);
  intent_filter_action["data"];
  intent_filter_action["uri-relative-filter-group"];
  intent_filter_action["uri-relative-filter-group"]["data"];

  // Common <meta-data> actions.
  xml::XmlNodeAction meta_data_action;

  // Common <property> actions.
  xml::XmlNodeAction property_action;
  property_action.Action(RequiredOneAndroidAttribute("resource", "value"));

  // Common <uses-feature> actions.
  xml::XmlNodeAction uses_feature_action;
  uses_feature_action.Action(VerifyUsesFeature);

  // Common component actions.
  xml::XmlNodeAction component_action;
  component_action.Action(RequiredNameIsJavaClassName);
  component_action.Action(
      [context](xml::Element* el) -> bool { return UpdateConfigChangesIfNeeded(el, context); });
  component_action["intent-filter"] = intent_filter_action;
  component_action["preferred"] = intent_filter_action;
  component_action["meta-data"] = meta_data_action;
  component_action["property"] = property_action;

  // Manifest actions.
  xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
  manifest_action.Action(AutoGenerateIsFeatureSplit);
  manifest_action.Action(AutoGenerateIsSplitRequired);
  manifest_action.Action(VerifyManifest);
  manifest_action.Action(FixCoreAppAttribute);
  manifest_action.Action([this, diag](xml::Element* el) -> bool {
    EnsureNamespaceIsDeclared("android", xml::kSchemaAndroid, &el->namespace_decls);

    if (options_.version_name_default) {
      if (options_.replace_version) {
        el->RemoveAttribute(xml::kSchemaAndroid, "versionName");
      }
      if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
        el->attributes.push_back(
            xml::Attribute{xml::kSchemaAndroid, "versionName",
                           options_.version_name_default.value()});
      }
    }

    if (options_.version_code_default) {
      if (options_.replace_version) {
        el->RemoveAttribute(xml::kSchemaAndroid, "versionCode");
      }
      if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
        el->attributes.push_back(
            xml::Attribute{xml::kSchemaAndroid, "versionCode",
                           options_.version_code_default.value()});
      }
    }

    if (options_.version_code_major_default) {
      if (options_.replace_version) {
        el->RemoveAttribute(xml::kSchemaAndroid, "versionCodeMajor");
      }
      if (el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor") == nullptr) {
        el->attributes.push_back(
            xml::Attribute{xml::kSchemaAndroid, "versionCodeMajor",
                           options_.version_code_major_default.value()});
      }
    }

    if (options_.revision_code_default) {
      if (options_.replace_version) {
        el->RemoveAttribute(xml::kSchemaAndroid, "revisionCode");
      }
      if (el->FindAttribute(xml::kSchemaAndroid, "revisionCode") == nullptr) {
        el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, "revisionCode",
                                                options_.revision_code_default.value()});
      }
    }

    if (options_.non_updatable_system) {
      if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
        el->RemoveAttribute("", "updatableSystem");
        el->attributes.push_back(xml::Attribute{"", "updatableSystem", "false"});
      } else {
        diag->Note(android::DiagMessage(el->line_number)
                   << "Ignoring --non-updatable-system because the manifest has a versionCode");
      }
    }

    return true;
  });

  // Meta tags.
  manifest_action["eat-comment"];

  // Uses-sdk actions.
  manifest_action["uses-sdk"].Action([this](xml::Element* el) -> bool {
    if (options_.min_sdk_version_default &&
        el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
      // There was no minSdkVersion defined and we have a default to assign.
      el->attributes.push_back(
          xml::Attribute{xml::kSchemaAndroid, "minSdkVersion",
                         options_.min_sdk_version_default.value()});
    }

    if (options_.target_sdk_version_default &&
        el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) {
      // There was no targetSdkVersion defined and we have a default to assign.
      el->attributes.push_back(
          xml::Attribute{xml::kSchemaAndroid, "targetSdkVersion",
                         options_.target_sdk_version_default.value()});
    }
    return true;
  });
  manifest_action["uses-sdk"]["extension-sdk"];

  // Instrumentation actions.
  manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
  manifest_action["instrumentation"].Action([this](xml::Element* el) -> bool {
    if (!options_.rename_instrumentation_target_package) {
      return true;
    }

    if (xml::Attribute* attr =
            el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
      attr->value = options_.rename_instrumentation_target_package.value();
    }
    return true;
  });
  manifest_action["instrumentation"]["meta-data"] = meta_data_action;

  manifest_action["attribution"];
  manifest_action["attribution"]["inherit-from"];
  manifest_action["original-package"];
  manifest_action["overlay"].Action([this](xml::Element* el) -> bool {
    if (options_.rename_overlay_target_package) {
      if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
        attr->value = options_.rename_overlay_target_package.value();
      }
    }
    if (options_.rename_overlay_category) {
      if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "category")) {
        attr->value = options_.rename_overlay_category.value();
      } else {
        el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, "category",
                                                options_.rename_overlay_category.value()});
      }
    }
    return true;
  });
  manifest_action["protected-broadcast"];
  manifest_action["adopt-permissions"];
  manifest_action["uses-permission"];
  manifest_action["uses-permission"]["required-feature"].Action(RequiredNameIsNotEmpty);
  manifest_action["uses-permission"]["required-not-feature"].Action(RequiredNameIsNotEmpty);
  manifest_action["uses-permission-sdk-23"];
  manifest_action["permission"];
  manifest_action["permission"]["meta-data"] = meta_data_action;
  manifest_action["permission-tree"];
  manifest_action["permission-group"];
  manifest_action["uses-configuration"];
  manifest_action["supports-screens"];
  manifest_action["uses-feature"] = uses_feature_action;
  manifest_action["feature-group"]["uses-feature"] = uses_feature_action;
  manifest_action["compatible-screens"];
  manifest_action["compatible-screens"]["screen"];
  manifest_action["supports-gl-texture"];
  manifest_action["restrict-update"];
  manifest_action["install-constraints"]["fingerprint-prefix"];
  manifest_action["package-verifier"];
  manifest_action["meta-data"] = meta_data_action;
  manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
  manifest_action["queries"]["package"].Action(RequiredNameIsJavaPackage);
  manifest_action["queries"]["intent"] = intent_filter_action;
  manifest_action["queries"]["provider"].Action(RequiredAndroidAttribute("authorities"));
  // TODO: more complicated component name tag

  manifest_action["key-sets"]["key-set"]["public-key"];
  manifest_action["key-sets"]["upgrade-key-set"];

  // Application actions.
  xml::XmlNodeAction& application_action = manifest_action["application"];
  application_action.Action(OptionalNameIsJavaClassName);

  application_action["uses-library"].Action(RequiredNameIsNotEmpty);
  application_action["uses-native-library"].Action(RequiredNameIsNotEmpty);
  application_action["library"].Action(RequiredNameIsNotEmpty);
  application_action["profileable"];
  application_action["property"] = property_action;

  xml::XmlNodeAction& static_library_action = application_action["static-library"];
  static_library_action.Action(RequiredNameIsJavaPackage);
  static_library_action.Action(RequiredAndroidAttribute("version"));

  xml::XmlNodeAction& uses_static_library_action = application_action["uses-static-library"];
  uses_static_library_action.Action(RequiredNameIsJavaPackage);
  uses_static_library_action.Action(RequiredAndroidAttribute("version"));
  uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
  uses_static_library_action["additional-certificate"];

  xml::XmlNodeAction& sdk_library_action = application_action["sdk-library"];
  sdk_library_action.Action(RequiredNameIsJavaPackage);
  sdk_library_action.Action(RequiredAndroidAttribute("versionMajor"));

  xml::XmlNodeAction& uses_sdk_library_action = application_action["uses-sdk-library"];
  uses_sdk_library_action.Action(RequiredNameIsJavaPackage);
  uses_sdk_library_action.Action(RequiredAndroidAttribute("versionMajor"));
  uses_sdk_library_action.Action(RequiredAndroidAttribute("certDigest"));
  uses_sdk_library_action["additional-certificate"];

  xml::XmlNodeAction& uses_package_action = application_action["uses-package"];
  uses_package_action.Action(RequiredNameIsJavaPackage);
  uses_package_action["additional-certificate"];

  if (options_.debug_mode) {
    application_action.Action([](xml::Element* el) -> bool {
      xml::Attribute *attr = el->FindOrCreateAttribute(xml::kSchemaAndroid, "debuggable");
      attr->value = "true";
      return true;
    });
  }

  application_action["meta-data"] = meta_data_action;

  application_action["processes"];
  application_action["processes"]["deny-permission"];
  application_action["processes"]["allow-permission"];
  application_action["processes"]["process"]["deny-permission"];
  application_action["processes"]["process"]["allow-permission"];

  application_action["activity"] = component_action;
  application_action["activity"]["layout"];

  application_action["activity-alias"] = component_action;
  application_action["service"] = component_action;
  application_action["receiver"] = component_action;
  application_action["apex-system-service"] = component_action;

  // Provider actions.
  application_action["provider"] = component_action;
  application_action["provider"]["grant-uri-permission"];
  application_action["provider"]["path-permission"];

  manifest_action["package"] = manifest_action;

  return true;
}

static void FullyQualifyClassName(StringPiece package, StringPiece attr_ns, StringPiece attr_name,
                                  xml::Element* el) {
  xml::Attribute* attr = el->FindAttribute(attr_ns, attr_name);
  if (attr != nullptr) {
    if (std::optional<std::string> new_value =
            util::GetFullyQualifiedClassName(package, attr->value)) {
      attr->value = std::move(new_value.value());
    }
  }
}

static bool RenameManifestPackage(StringPiece package_override, xml::Element* manifest_el) {
  xml::Attribute* attr = manifest_el->FindAttribute({}, "package");

  // We've already verified that the manifest element is present, with a package
  // name specified.
  CHECK(attr != nullptr);

  std::string original_package = std::move(attr->value);
  attr->value.assign(package_override);

  xml::Element* application_el = manifest_el->FindChild({}, "application");
  if (application_el != nullptr) {
    FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", application_el);
    FullyQualifyClassName(original_package, xml::kSchemaAndroid, "backupAgent", application_el);

    for (xml::Element* child_el : application_el->GetChildElements()) {
      if (child_el->namespace_uri.empty()) {
        if (child_el->name == "activity" || child_el->name == "activity-alias" ||
            child_el->name == "provider" || child_el->name == "receiver" ||
            child_el->name == "service") {
          FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", child_el);
          continue;
        }

        if (child_el->name == "activity-alias") {
          FullyQualifyClassName(original_package, xml::kSchemaAndroid, "targetActivity", child_el);
          continue;
        }

        if (child_el->name == "processes") {
          for (xml::Element* grand_child_el : child_el->GetChildElements()) {
            if (grand_child_el->name == "process") {
              FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", grand_child_el);
            }
          }
          continue;
        }
      }
    }
  }
  return true;
}

bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
  TRACE_CALL();
  xml::Element* root = xml::FindRootElement(doc->root.get());
  if (!root || !root->namespace_uri.empty() || root->name != "manifest") {
    context->GetDiagnostics()->Error(android::DiagMessage(doc->file.source)
                                     << "root tag must be <manifest>");
    return false;
  }

  if ((options_.min_sdk_version_default || options_.target_sdk_version_default) &&
      root->FindChild({}, "uses-sdk") == nullptr) {
    // Auto insert a <uses-sdk> element. This must be inserted before the
    // <application> tag. The device runtime PackageParser will make SDK version
    // decisions while parsing <application>.
    std::unique_ptr<xml::Element> uses_sdk = util::make_unique<xml::Element>();
    uses_sdk->name = "uses-sdk";
    root->InsertChild(0, std::move(uses_sdk));
  }

  if (!options_.no_compile_sdk_metadata && options_.compile_sdk_version) {
    xml::Attribute* attr = root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersion");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};
    attr->value = options_.compile_sdk_version.value();

    attr = root->FindOrCreateAttribute("", "platformBuildVersionCode");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};
    attr->value = options_.compile_sdk_version.value();
  }

  if (!options_.no_compile_sdk_metadata && options_.compile_sdk_version_codename) {
    xml::Attribute* attr =
        root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};
    attr->value = options_.compile_sdk_version_codename.value();

    attr = root->FindOrCreateAttribute("", "platformBuildVersionName");

    // Make sure we un-compile the value if it was set to something else.
    attr->compiled_value = {};
    attr->value = options_.compile_sdk_version_codename.value();
  }

  if (!options_.fingerprint_prefixes.empty()) {
    xml::Element* install_constraints_el = root->FindChild({}, "install-constraints");
    if (install_constraints_el == nullptr) {
      std::unique_ptr<xml::Element> install_constraints = std::make_unique<xml::Element>();
      install_constraints->name = "install-constraints";
      install_constraints_el = install_constraints.get();
      root->AppendChild(std::move(install_constraints));
    }
    for (const std::string& prefix : options_.fingerprint_prefixes) {
      std::unique_ptr<xml::Element> prefix_el = std::make_unique<xml::Element>();
      prefix_el->name = "fingerprint-prefix";
      xml::Attribute* attr = prefix_el->FindOrCreateAttribute(xml::kSchemaAndroid, "value");
      attr->value = prefix;
      install_constraints_el->AppendChild(std::move(prefix_el));
    }
  }

  xml::XmlActionExecutor executor;
  if (!BuildRules(&executor, context)) {
    return false;
  }

  xml::XmlActionExecutorPolicy policy = options_.warn_validation
                                            ? xml::XmlActionExecutorPolicy::kAllowListWarning
                                            : xml::XmlActionExecutorPolicy::kAllowList;
  if (!executor.Execute(policy, context->GetDiagnostics(), doc)) {
    return false;
  }

  if (options_.rename_manifest_package) {
    // Rename manifest package outside of the XmlActionExecutor.
    // We need to extract the old package name and FullyQualify all class
    // names.
    if (!RenameManifestPackage(options_.rename_manifest_package.value(), root)) {
      return false;
    }
  }
  return true;
}

}  // namespace aapt
