/*
 * 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 "android-base/logging.h"

#include "ResourceUtils.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 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, android::IDiagnostics* diag) {
  // First verify some options.
  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["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([&](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()});
      }
    }

    return true;
  });

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

  // Uses-sdk actions.
  manifest_action["uses-sdk"].Action([&](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([&](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([&](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->GetDiagnostics())) {
    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
