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

#include "android-base/logging.h"

#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "trace/TraceBuffer.h"
#include "ValueVisitor.h"
#include "util/Util.h"

using ::android::StringPiece;

namespace aapt {

TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table,
                         const TableMergerOptions& options)
    : context_(context), main_table_(out_table), options_(options) {
  // Create the desired package that all tables will be merged into.
  main_package_ = main_table_->FindOrCreatePackage(context_->GetCompilationPackage());
  CHECK(main_package_ != nullptr) << "package name or ID already taken";
}

bool TableMerger::Merge(const android::Source& src, ResourceTable* table, bool overlay) {
  TRACE_CALL();
  // We allow adding new resources if this is not an overlay, or if the options allow overlays
  // to add new resources.
  return MergeImpl(src, table, overlay, options_.auto_add_overlay || !overlay /*allow_new*/);
}

// This will merge packages with the same package name (or no package name).
bool TableMerger::MergeImpl(const android::Source& src, ResourceTable* table, bool overlay,
                            bool allow_new) {
  bool error = false;
  for (auto& package : table->packages) {
    // Only merge an empty package or the package we're building.
    // Other packages may exist, which likely contain attribute definitions.
    // This is because at compile time it is unknown if the attributes are
    // simply uses of the attribute or definitions.
    if (package->name.empty() || context_->GetCompilationPackage() == package->name) {
      // Merge here. Once the entries are merged and mangled, any references to them are still
      // valid. This is because un-mangled references are mangled, then looked up at resolution
      // time. Also, when linking, we convert references with no package name to use the compilation
      // package name.
      error |= !DoMerge(src, package.get(), false /*mangle*/, overlay, allow_new);
    }
  }
  return !error;
}

// This will merge and mangle resources from a static library. It is assumed that all FileReferences
// have correctly set their io::IFile*.
bool TableMerger::MergeAndMangle(const android::Source& src, StringPiece package_name,
                                 ResourceTable* table) {
  bool error = false;
  for (auto& package : table->packages) {
    // Warn of packages with an unrelated ID.
    if (package_name != package->name) {
      context_->GetDiagnostics()->Warn(android::DiagMessage(src)
                                       << "ignoring package " << package->name);
      continue;
    }

    bool mangle = package_name != context_->GetCompilationPackage();
    merged_packages_.insert(package->name);
    error |= !DoMerge(src, package.get(), mangle, false /*overlay*/, true /*allow_new*/);
  }
  return !error;
}

static bool MergeType(IAaptContext* context, const android::Source& src,
                      ResourceTableType* dst_type, ResourceTableType* src_type) {
  if (src_type->visibility_level >= dst_type->visibility_level) {
    // The incoming type's visibility is stronger, so we should override the visibility.
    dst_type->visibility_level = src_type->visibility_level;
  }
  return true;
}

static bool MergeEntry(IAaptContext* context, const android::Source& src, ResourceEntry* dst_entry,
                       ResourceEntry* src_entry, bool strict_visibility) {
  if (strict_visibility
      && dst_entry->visibility.level != Visibility::Level::kUndefined
      && src_entry->visibility.level != dst_entry->visibility.level) {
    context->GetDiagnostics()->Error(android::DiagMessage(src)
                                     << "cannot merge resource '" << dst_entry->name
                                     << "' with conflicting visibilities: "
                                     << "public and private");
    return false;
  }

  // Copy over the strongest visibility.
  if (src_entry->visibility.level > dst_entry->visibility.level) {
    // Only copy the ID if the source is public, or else the ID is meaningless.
    if (src_entry->visibility.level == Visibility::Level::kPublic) {
      dst_entry->id = src_entry->id;
    }
    dst_entry->visibility = std::move(src_entry->visibility);
  } else if (src_entry->visibility.level == Visibility::Level::kPublic &&
             dst_entry->visibility.level == Visibility::Level::kPublic && dst_entry->id &&
             src_entry->id && src_entry->id != dst_entry->id) {
    // Both entries are public and have different IDs.
    context->GetDiagnostics()->Error(android::DiagMessage(src)
                                     << "cannot merge entry '" << src_entry->name
                                     << "': conflicting public IDs");
    return false;
  }

  // Copy over the rest of the properties, if needed.
  if (src_entry->allow_new) {
    dst_entry->allow_new = std::move(src_entry->allow_new);
  }

  if (src_entry->overlayable_item) {
    if (dst_entry->overlayable_item) {
      CHECK(src_entry->overlayable_item.value().overlayable != nullptr);
      Overlayable* src_overlayable = src_entry->overlayable_item.value().overlayable.get();

      CHECK(dst_entry->overlayable_item.value().overlayable != nullptr);
      Overlayable* dst_overlayable = dst_entry->overlayable_item.value().overlayable.get();

      if (src_overlayable->name != dst_overlayable->name
          || src_overlayable->actor != dst_overlayable->actor
          || src_entry->overlayable_item.value().policies !=
             dst_entry->overlayable_item.value().policies) {

        // Do not allow a resource with an overlayable declaration to have that overlayable
        // declaration redefined.
        context->GetDiagnostics()->Error(
            android::DiagMessage(src_entry->overlayable_item.value().source)
            << "duplicate overlayable declaration for resource '" << src_entry->name << "'");
        context->GetDiagnostics()->Error(
            android::DiagMessage(dst_entry->overlayable_item.value().source)
            << "previous declaration here");
        return false;
      }
    }

    dst_entry->overlayable_item = std::move(src_entry->overlayable_item);
  }

  if (src_entry->staged_id) {
    if (dst_entry->staged_id &&
        dst_entry->staged_id.value().id != src_entry->staged_id.value().id) {
      context->GetDiagnostics()->Error(android::DiagMessage(src_entry->staged_id.value().source)
                                       << "conflicting staged id declaration for resource '"
                                       << src_entry->name << "'");
      context->GetDiagnostics()->Error(android::DiagMessage(dst_entry->staged_id.value().source)
                                       << "previous declaration here");
    }
    dst_entry->staged_id = std::move(src_entry->staged_id);
  }

  return true;
}

// Modified CollisionResolver which will merge Styleables and Styles. Used with overlays.
//
// Styleables are not actual resources, but they are treated as such during the compilation phase.
//
// Styleables and Styles don't simply overlay each other, their definitions merge and accumulate.
// If both values are Styleables/Styles, we just merge them into the existing value.
static ResourceTable::CollisionResult ResolveMergeCollision(
    bool override_styles_instead_of_overlaying, Value* existing, Value* incoming,
    android::StringPool* pool) {
  if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) {
    if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) {
      // Styleables get merged.
      existing_styleable->MergeWith(incoming_styleable);
      return ResourceTable::CollisionResult::kKeepOriginal;
    }
  } else if (!override_styles_instead_of_overlaying) {
    if (Style* existing_style = ValueCast<Style>(existing)) {
      if (Style* incoming_style = ValueCast<Style>(incoming)) {
        // Styles get merged.
        existing_style->MergeWith(incoming_style, pool);
        return ResourceTable::CollisionResult::kKeepOriginal;
      }
    }
  }
  // Delegate to the default handler.
  return ResourceTable::ResolveValueCollision(existing, incoming);
}

static ResourceTable::CollisionResult MergeConfigValue(
    IAaptContext* context, const ResourceNameRef& res_name, bool overlay,
    bool override_styles_instead_of_overlaying, ResourceConfigValue* dst_config_value,
    ResourceConfigValue* src_config_value, android::StringPool* pool) {
  using CollisionResult = ResourceTable::CollisionResult;

  Value* dst_value = dst_config_value->value.get();
  Value* src_value = src_config_value->value.get();

  CollisionResult collision_result =
      ResourceTable::ResolveFlagCollision(dst_value->GetFlagStatus(), src_value->GetFlagStatus());
  if (collision_result == CollisionResult::kConflict) {
    if (overlay) {
      collision_result =
          ResolveMergeCollision(override_styles_instead_of_overlaying, dst_value, src_value, pool);
    } else {
      collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
    }
  }

  if (collision_result == CollisionResult::kConflict) {
    if (overlay) {
      return CollisionResult::kTakeNew;
    }

    // Error!
    context->GetDiagnostics()->Error(android::DiagMessage(src_value->GetSource())
                                     << "resource '" << res_name << "' has a conflicting value for "
                                     << "configuration (" << src_config_value->config << ")");
    context->GetDiagnostics()->Note(android::DiagMessage(dst_value->GetSource())
                                    << "originally defined here");
    return CollisionResult::kConflict;
  }
  return collision_result;
}

bool TableMerger::MergeConfigValues(const char* config_value_section, ResourceNameRef res_name,
                                    bool overlay,
                                    const std::vector<std::unique_ptr<ResourceConfigValue>>& values,
                                    FindFunc find_function, FindFunc find_or_create_function) {
  using CollisionResult = ResourceTable::CollisionResult;
  bool error = false;

  for (auto& src_config_value : values) {
    ResourceConfigValue* dst_config_value =
        find_function(src_config_value->value->GetFlag().value(), src_config_value->config,
                      src_config_value->product);
    if (dst_config_value) {
      CollisionResult collision_result = MergeConfigValue(
          context_, res_name, overlay, options_.override_styles_instead_of_overlaying,
          dst_config_value, src_config_value.get(), &main_table_->string_pool);
      if (collision_result == CollisionResult::kConflict) {
        context_->GetDiagnostics()->Error(
            android::DiagMessage(src_config_value->value->GetSource())
            << "duplicate " << config_value_section << " value for resource '"
            << res_name.to_string() << "' " << "with config '" << src_config_value->config
            << "' and flag '" << (src_config_value->value->GetFlag()->negated ? "!" : "")
            << src_config_value->value->GetFlag()->name << "'");
        context_->GetDiagnostics()->Note(android::DiagMessage(dst_config_value->value->GetSource())
                                         << "resource previously defined here");
        error = true;
        continue;
      } else if (collision_result == CollisionResult::kKeepOriginal) {
        continue;
      }
    } else {
      dst_config_value =
          find_or_create_function(src_config_value->value->GetFlag().value(),
                                  src_config_value->config, src_config_value->product);
      // Resource does not exist, add it now.
      // Must clone the value since it might be in the values vector as well
      CloningValueTransformer cloner(&main_table_->string_pool);
      dst_config_value->value = src_config_value->value->Transform(cloner);
    }
  }
  return !error;
}

bool TableMerger::DoMerge(const android::Source& src, ResourceTablePackage* src_package,
                          bool mangle_package, bool overlay, bool allow_new_resources) {
  bool error = false;

  for (auto& src_type : src_package->types) {
    ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->named_type);
    if (!MergeType(context_, src, dst_type, src_type.get())) {
      error = true;
      continue;
    }

    for (auto& src_entry : src_type->entries) {
      std::string entry_name = src_entry->name;
      if (mangle_package) {
        entry_name = NameMangler::MangleEntry(src_package->name, src_entry->name);
      }

      ResourceEntry* dst_entry;
      if (allow_new_resources || src_entry->allow_new) {
        dst_entry = dst_type->FindOrCreateEntry(entry_name);
      } else {
        dst_entry = dst_type->FindEntry(entry_name);
      }

      const ResourceNameRef res_name(src_package->name, src_type->named_type, src_entry->name);

      if (!dst_entry) {
        context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                          << "resource " << res_name
                                          << " does not override an existing resource");
        context_->GetDiagnostics()->Note(android::DiagMessage(src)
                                         << "define an <add-resource> tag or use "
                                         << "--auto-add-overlay");
        error = true;
        continue;
      }

      if (!MergeEntry(context_, src, dst_entry, src_entry.get(), options_.strict_visibility)) {
        error = true;
        continue;
      }

      for (auto& src_config_value : src_entry->values) {
        using CollisionResult = ResourceTable::CollisionResult;

        ResourceConfigValue* dst_config_value = dst_entry->FindValue(
            src_config_value->config, src_config_value->product);
        if (dst_config_value) {
          CollisionResult collision_result = MergeConfigValue(
              context_, res_name, overlay, options_.override_styles_instead_of_overlaying,
              dst_config_value, src_config_value.get(), &main_table_->string_pool);
          if (collision_result == CollisionResult::kConflict) {
            error = true;
            continue;
          } else if (collision_result == CollisionResult::kKeepOriginal) {
            continue;
          }
        } else {
          dst_config_value =
              dst_entry->FindOrCreateValue(src_config_value->config, src_config_value->product);
        }
        dst_config_value->uses_readwrite_feature_flags |=
            src_config_value->uses_readwrite_feature_flags;

        // Continue if we're taking the new resource.
        CloningValueTransformer cloner(&main_table_->string_pool);
        if (FileReference* f = ValueCast<FileReference>(src_config_value->value.get())) {
          std::unique_ptr<FileReference> new_file_ref;
          if (mangle_package) {
            new_file_ref = CloneAndMangleFile(src_package->name, *f);
          } else {
            new_file_ref = std::unique_ptr<FileReference>(f->Transform(cloner));
          }
          dst_config_value->value = std::move(new_file_ref);

        } else {
          auto original_comment = (dst_config_value->value)
              ? dst_config_value->value->GetComment() : std::optional<std::string>();

          dst_config_value->value = src_config_value->value->Transform(cloner);

          // Keep the comment from the original resource and ignore all comments from overlaying
          // resources
          if (overlay && original_comment) {
            dst_config_value->value->SetComment(original_comment.value());
          }
        }
      }

      // disabled values
      MergeConfigValues(
          "flag_disabled_values", res_name, overlay, src_entry->flag_disabled_values,
          [&](const FeatureFlagAttribute& flag, const android::ConfigDescription& config,
              const std::string& product) {
            return dst_entry->FindFlagDisabledValue(flag, config, product);
          },
          [&](const FeatureFlagAttribute& flag, const android::ConfigDescription& config,
              const std::string& product) {
            return dst_entry->FindOrCreateFlagDisabledValue(flag, config, product);
          });

      // read/write flag values
      MergeConfigValues(
          "readwrite_flag_values", res_name, overlay, src_entry->readwrite_flag_values,
          [&](const FeatureFlagAttribute& flag, const android::ConfigDescription& config,
              const std::string& product) {
            return dst_entry->FindReadWriteFlagValue(flag, config, product);
          },
          [&](const FeatureFlagAttribute& flag, const android::ConfigDescription& config,
              const std::string& product) {
            return dst_entry->FindOrCreateReadWriteFlagValue(flag, config, product);
          });
    }
  }
  return !error;
}

std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile(
    const std::string& package, const FileReference& file_ref) {
  StringPiece prefix, entry, suffix;
  if (util::ExtractResFilePathParts(*file_ref.path, &prefix, &entry, &suffix)) {
    std::string mangled_entry = NameMangler::MangleEntry(package, entry);
    std::string newPath = (std::string(prefix) += mangled_entry) += suffix;
    std::unique_ptr<FileReference> new_file_ref =
        util::make_unique<FileReference>(main_table_->string_pool.MakeRef(newPath));
    new_file_ref->SetComment(file_ref.GetComment());
    new_file_ref->SetSource(file_ref.GetSource());
    new_file_ref->type = file_ref.type;
    new_file_ref->file = file_ref.file;
    return new_file_ref;
  }

  CloningValueTransformer cloner(&main_table_->string_pool);
  return std::unique_ptr<FileReference>(file_ref.Transform(cloner));
}

bool TableMerger::MergeFile(const ResourceFile& file_desc, bool overlay, io::IFile* file) {
  ResourceTable table;
  std::string path = ResourceUtils::BuildResourceFileName(file_desc);
  std::unique_ptr<FileReference> file_ref =
      util::make_unique<FileReference>(table.string_pool.MakeRef(path));
  file_ref->SetSource(file_desc.source);
  file_ref->type = file_desc.type;
  file_ref->file = file;
  file_ref->SetFlagStatus(file_desc.flag_status);
  file_ref->SetFlag(file_desc.flag);
  ResourceTablePackage* pkg = table.FindOrCreatePackage(file_desc.name.package);
  ResourceConfigValue* config_value = pkg->FindOrCreateType(file_desc.name.type)
                                          ->FindOrCreateEntry(file_desc.name.entry)
                                          ->FindOrCreateValue(file_desc.config, {});

  config_value->value = std::move(file_ref);
  config_value->uses_readwrite_feature_flags = file_desc.uses_readwrite_feature_flags;

  return DoMerge(file->GetSource(), pkg, false /*mangle*/, overlay /*overlay*/, true /*allow_new*/);
}

}  // namespace aapt
