/*
 * Copyright (C) 2019 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 "idmap2/ResourceMapping.h"

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "android-base/stringprintf.h"
#include "idmap2/ResourceUtils.h"

using android::base::StringPrintf;
using android::idmap2::utils::ResToTypeEntryName;

namespace android::idmap2 {

namespace {

#define EXTRACT_PACKAGE(resid) ((0xff000000 & (resid)) >> 24)

std::string ConcatPolicies(const std::vector<std::string>& policies) {
  std::string message;
  for (const std::string& policy : policies) {
    if (!message.empty()) {
      message.append("|");
    }
    message.append(policy);
  }

  return message;
}

Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
                              const OverlayManifestInfo& overlay_info,
                              const PolicyBitmask& fulfilled_policies,
                              const ResourceId& target_resource) {
  static constexpr const PolicyBitmask sDefaultPolicies =
      PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION |
      PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION |
      PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE;

  // If the resource does not have an overlayable definition, allow the resource to be overlaid if
  // the overlay is preinstalled or signed with the same signature as the target.
  if (!target_package.DefinesOverlayable()) {
    return (sDefaultPolicies & fulfilled_policies) != 0
               ? Result<Unit>({})
               : Error(
                     "overlay must be preinstalled or signed with the same signature as the "
                     "target");
  }

  const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(target_resource);
  if (overlayable_info == nullptr) {
    // Do not allow non-overlayable resources to be overlaid.
    return Error("target resource has no overlayable declaration");
  }

  if (overlay_info.target_name != overlayable_info->name) {
    // If the overlay supplies a target overlayable name, the resource must belong to the
    // overlayable defined with the specified name to be overlaid.
    return Error(R"(<overlay> android:targetName "%s" does not match overlayable name "%s")",
                 overlay_info.target_name.c_str(), overlayable_info->name.c_str());
  }

  // Enforce policy restrictions if the resource is declared as overlayable.
  if ((overlayable_info->policy_flags & fulfilled_policies) == 0) {
    return Error(R"(overlay with policies "%s" does not fulfill any overlayable policies "%s")",
                 ConcatPolicies(BitmaskToPolicies(fulfilled_policies)).c_str(),
                 ConcatPolicies(BitmaskToPolicies(overlayable_info->policy_flags)).c_str());
  }

  return Result<Unit>({});
}

// TODO(martenkongstad): scan for package name instead of assuming package at index 0
//
// idmap version 0x01 naively assumes that the package to use is always the first ResTable_package
// in the resources.arsc blob. In most cases, there is only a single ResTable_package anyway, so
// this assumption tends to work out. That said, the correct thing to do is to scan
// resources.arsc for a package with a given name as read from the package manifest instead of
// relying on a hard-coded index. This however requires storing the package name in the idmap
// header, which in turn requires incrementing the idmap version. Because the initial version of
// idmap2 is compatible with idmap, this will have to wait for now.
const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) {
  const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc.GetPackages();
  if (packages.empty()) {
    return nullptr;
  }
  int id = packages[0]->GetPackageId();
  return loaded_arsc.GetPackageById(id);
}

Result<std::unique_ptr<Asset>> OpenNonAssetFromResource(const ResourceId& resource_id,
                                                        const AssetManager2& asset_manager) {
  Res_value value{};
  ResTable_config selected_config{};
  uint32_t flags;
  auto cookie =
      asset_manager.GetResource(resource_id, /* may_be_bag */ false,
                                /* density_override */ 0U, &value, &selected_config, &flags);
  if (cookie == kInvalidCookie) {
    return Error("failed to find resource for id 0x%08x", resource_id);
  }

  if (value.dataType != Res_value::TYPE_STRING) {
    return Error("resource for is 0x%08x is not a file", resource_id);
  }

  auto string_pool = asset_manager.GetStringPoolForCookie(cookie);
  size_t len;
  auto file_path16 = string_pool->stringAt(value.data, &len);
  if (file_path16 == nullptr) {
    return Error("failed to find string for index %d", value.data);
  }

  // Load the overlay resource mappings from the file specified using android:resourcesMap.
  auto file_path = String8(String16(file_path16));
  auto asset = asset_manager.OpenNonAsset(file_path.c_str(), Asset::AccessMode::ACCESS_BUFFER);
  if (asset == nullptr) {
    return Error("file \"%s\" not found", file_path.c_str());
  }

  return asset;
}

}  // namespace

Result<ResourceMapping> ResourceMapping::CreateResourceMapping(const AssetManager2* target_am,
                                                               const LoadedPackage* target_package,
                                                               const LoadedPackage* overlay_package,
                                                               size_t string_pool_offset,
                                                               const XmlParser& overlay_parser,
                                                               LogInfo& log_info) {
  ResourceMapping resource_mapping;
  auto root_it = overlay_parser.tree_iterator();
  if (root_it->event() != XmlParser::Event::START_TAG || root_it->name() != "overlay") {
    return Error("root element is not <overlay> tag");
  }

  const uint8_t overlay_package_id = overlay_package->GetPackageId();
  auto overlay_it_end = root_it.end();
  for (auto overlay_it = root_it.begin(); overlay_it != overlay_it_end; ++overlay_it) {
    if (overlay_it->event() == XmlParser::Event::BAD_DOCUMENT) {
      return Error("failed to parse overlay xml document");
    }

    if (overlay_it->event() != XmlParser::Event::START_TAG) {
      continue;
    }

    if (overlay_it->name() != "item") {
      return Error("unexpected tag <%s> in <overlay>", overlay_it->name().c_str());
    }

    Result<std::string> target_resource = overlay_it->GetAttributeStringValue("target");
    if (!target_resource) {
      return Error(R"(<item> tag missing expected attribute "target")");
    }

    Result<android::Res_value> overlay_resource = overlay_it->GetAttributeValue("value");
    if (!overlay_resource) {
      return Error(R"(<item> tag missing expected attribute "value")");
    }

    ResourceId target_id =
        target_am->GetResourceId(*target_resource, "", target_package->GetPackageName());
    if (target_id == 0U) {
      log_info.Warning(LogMessage() << "failed to find resource \"" << *target_resource
                                    << "\" in target resources");
      continue;
    }

    if (overlay_resource->dataType == Res_value::TYPE_STRING) {
      overlay_resource->data += string_pool_offset;
    }

    // Only rewrite resources defined within the overlay package to their corresponding target
    // resource ids at runtime.
    bool rewrite_overlay_reference =
        (overlay_resource->dataType == Res_value::TYPE_REFERENCE ||
         overlay_resource->dataType == Res_value::TYPE_DYNAMIC_REFERENCE)
            ? overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data)
            : false;

    if (rewrite_overlay_reference) {
      overlay_resource->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;
    }

    resource_mapping.AddMapping(target_id, overlay_resource->dataType, overlay_resource->data,
                                rewrite_overlay_reference);
  }

  return resource_mapping;
}

Result<ResourceMapping> ResourceMapping::CreateResourceMappingLegacy(
    const AssetManager2* target_am, const AssetManager2* overlay_am,
    const LoadedPackage* target_package, const LoadedPackage* overlay_package) {
  ResourceMapping resource_mapping;
  const auto end = overlay_package->end();
  for (auto iter = overlay_package->begin(); iter != end; ++iter) {
    const ResourceId overlay_resid = *iter;
    Result<std::string> name = utils::ResToTypeEntryName(*overlay_am, overlay_resid);
    if (!name) {
      continue;
    }

    // Find the resource with the same type and entry name within the target package.
    const std::string full_name =
        base::StringPrintf("%s:%s", target_package->GetPackageName().c_str(), name->c_str());
    const ResourceId target_resource = target_am->GetResourceId(full_name);
    if (target_resource == 0U) {
      continue;
    }

    resource_mapping.AddMapping(target_resource, Res_value::TYPE_REFERENCE, overlay_resid,
                                /* rewrite_overlay_reference */ false);
  }

  return resource_mapping;
}

void ResourceMapping::FilterOverlayableResources(const AssetManager2* target_am,
                                                 const LoadedPackage* target_package,
                                                 const LoadedPackage* overlay_package,
                                                 const OverlayManifestInfo& overlay_info,
                                                 const PolicyBitmask& fulfilled_policies,
                                                 LogInfo& log_info) {
  std::set<ResourceId> remove_ids;
  for (const auto& target_map : target_map_) {
    const ResourceId target_resid = target_map.first;
    Result<Unit> success =
        CheckOverlayable(*target_package, overlay_info, fulfilled_policies, target_resid);
    if (success) {
      continue;
    }

    // Attempting to overlay a resource that is not allowed to be overlaid is treated as a
    // warning.
    Result<std::string> name = utils::ResToTypeEntryName(*target_am, target_resid);
    if (!name) {
      name = StringPrintf("0x%08x", target_resid);
    }

    log_info.Warning(LogMessage() << "overlay \"" << overlay_package->GetPackageName()
                                  << "\" is not allowed to overlay resource \"" << *name
                                  << "\" in target: " << success.GetErrorMessage());

    remove_ids.insert(target_resid);
  }

  for (const ResourceId target_resid : remove_ids) {
    RemoveMapping(target_resid);
  }
}

Result<ResourceMapping> ResourceMapping::FromApkAssets(const ApkAssets& target_apk_assets,
                                                       const ApkAssets& overlay_apk_assets,
                                                       const OverlayManifestInfo& overlay_info,
                                                       const PolicyBitmask& fulfilled_policies,
                                                       bool enforce_overlayable,
                                                       LogInfo& log_info) {
  if (enforce_overlayable) {
    log_info.Info(LogMessage() << "fulfilled_policies="
                               << ConcatPolicies(BitmaskToPolicies(fulfilled_policies))
                               << " enforce_overlayable="
                               << (enforce_overlayable ? "true" : "false"));
  }

  AssetManager2 target_asset_manager;
  if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true /* invalidate_caches */,
                                         false /* filter_incompatible_configs*/)) {
    return Error("failed to create target asset manager");
  }

  AssetManager2 overlay_asset_manager;
  if (!overlay_asset_manager.SetApkAssets({&overlay_apk_assets}, true /* invalidate_caches */,
                                          false /* filter_incompatible_configs */)) {
    return Error("failed to create overlay asset manager");
  }

  const LoadedArsc* target_arsc = target_apk_assets.GetLoadedArsc();
  if (target_arsc == nullptr) {
    return Error("failed to load target resources.arsc");
  }

  const LoadedArsc* overlay_arsc = overlay_apk_assets.GetLoadedArsc();
  if (overlay_arsc == nullptr) {
    return Error("failed to load overlay resources.arsc");
  }

  const LoadedPackage* target_pkg = GetPackageAtIndex0(*target_arsc);
  if (target_pkg == nullptr) {
    return Error("failed to load target package from resources.arsc");
  }

  const LoadedPackage* overlay_pkg = GetPackageAtIndex0(*overlay_arsc);
  if (overlay_pkg == nullptr) {
    return Error("failed to load overlay package from resources.arsc");
  }

  size_t string_pool_data_length = 0U;
  size_t string_pool_offset = 0U;
  std::unique_ptr<uint8_t[]> string_pool_data;
  Result<ResourceMapping> resource_mapping = {{}};
  if (overlay_info.resource_mapping != 0U) {
    // Load the overlay resource mappings from the file specified using android:resourcesMap.
    auto asset = OpenNonAssetFromResource(overlay_info.resource_mapping, overlay_asset_manager);
    if (!asset) {
      return Error("failed opening xml for android:resourcesMap: %s",
                   asset.GetErrorMessage().c_str());
    }

    auto parser =
        XmlParser::Create((*asset)->getBuffer(true /* wordAligned*/), (*asset)->getLength());
    if (!parser) {
      return Error("failed opening ResXMLTree");
    }

    // Copy the xml string pool data before the parse goes out of scope.
    auto& string_pool = (*parser)->get_strings();
    string_pool_data_length = string_pool.bytes();
    string_pool_data.reset(new uint8_t[string_pool_data_length]);
    memcpy(string_pool_data.get(), string_pool.data(), string_pool_data_length);

    // Offset string indices by the size of the overlay resource table string pool.
    string_pool_offset = overlay_arsc->GetStringPool()->size();

    resource_mapping = CreateResourceMapping(&target_asset_manager, target_pkg, overlay_pkg,
                                             string_pool_offset, *(*parser), log_info);
  } else {
    // If no file is specified using android:resourcesMap, it is assumed that the overlay only
    // defines resources intended to override target resources of the same type and name.
    resource_mapping = CreateResourceMappingLegacy(&target_asset_manager, &overlay_asset_manager,
                                                   target_pkg, overlay_pkg);
  }

  if (!resource_mapping) {
    return resource_mapping.GetError();
  }

  if (enforce_overlayable) {
    // Filter out resources the overlay is not allowed to override.
    (*resource_mapping)
        .FilterOverlayableResources(&target_asset_manager, target_pkg, overlay_pkg, overlay_info,
                                    fulfilled_policies, log_info);
  }

  resource_mapping->target_package_id_ = target_pkg->GetPackageId();
  resource_mapping->overlay_package_id_ = overlay_pkg->GetPackageId();
  resource_mapping->string_pool_offset_ = string_pool_offset;
  resource_mapping->string_pool_data_ = std::move(string_pool_data);
  resource_mapping->string_pool_data_length_ = string_pool_data_length;
  return std::move(*resource_mapping);
}

OverlayResourceMap ResourceMapping::GetOverlayToTargetMap() const {
  // An overlay resource can override multiple target resources at once. Rewrite the overlay
  // resource as the first target resource it overrides.
  OverlayResourceMap map;
  for (const auto& mappings : overlay_map_) {
    map.insert(std::make_pair(mappings.first, mappings.second));
  }
  return map;
}

Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource,
                                         TargetValue::DataType data_type,
                                         TargetValue::DataValue data_value,
                                         bool rewrite_overlay_reference) {
  if (target_map_.find(target_resource) != target_map_.end()) {
    return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource);
  }

  // TODO(141485591): Ensure that the overlay type is compatible with the target type. If the
  // runtime types are not compatible, it could cause runtime crashes when the resource is resolved.

  target_map_.insert(std::make_pair(target_resource, TargetValue{data_type, data_value}));

  if (rewrite_overlay_reference &&
      (data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE)) {
    overlay_map_.insert(std::make_pair(data_value, target_resource));
  }

  return Result<Unit>({});
}

void ResourceMapping::RemoveMapping(ResourceId target_resource) {
  auto target_iter = target_map_.find(target_resource);
  if (target_iter == target_map_.end()) {
    return;
  }

  const TargetValue value = target_iter->second;
  target_map_.erase(target_iter);

  if (value.data_type != Res_value::TYPE_REFERENCE &&
      value.data_type != Res_value::TYPE_DYNAMIC_REFERENCE) {
    return;
  }

  auto overlay_iter = overlay_map_.equal_range(value.data_value);
  for (auto i = overlay_iter.first; i != overlay_iter.second; ++i) {
    if (i->second == target_resource) {
      overlay_map_.erase(i);
      return;
    }
  }
}

}  // namespace android::idmap2
