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

#include "ResourceParser.h"
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/ResourceTypes.h"
#include "link/Linkers.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlUtil.h"

using ::aapt::ResourceUtils::StringBuilder;
using ::android::StringPiece;
using ::android::base::StringPrintf;

namespace aapt {
namespace {
struct LoggingResourceName {
  LoggingResourceName(const Reference& ref, const CallSite& callsite,
                      const xml::IPackageDeclStack* decls)
      : ref_(ref), callsite_(callsite), decls_(decls) {
  }

  const Reference& ref_;
  const CallSite& callsite_;
  const xml::IPackageDeclStack* decls_;
};

inline ::std::ostream& operator<<(::std::ostream& out, const LoggingResourceName& name) {
  if (!name.ref_.name) {
    out << name.ref_.id.value();
    return out;
  }

  out << name.ref_.name.value();

  Reference fully_qualified = name.ref_;
  xml::ResolvePackage(name.decls_, &fully_qualified);

  ResourceName& full_name = fully_qualified.name.value();
  if (full_name.package.empty()) {
    full_name.package = name.callsite_.package;
  }

  if (full_name != name.ref_.name.value()) {
    out << " (aka " << full_name << ")";
  }
  return out;
}

}  // namespace

std::unique_ptr<Reference> ReferenceLinkerTransformer::TransformDerived(const Reference* value) {
  auto linked_item =
      ReferenceLinker::LinkReference(callsite_, *value, context_, symbols_, table_, package_decls_);
  if (linked_item) {
    auto linked_item_ptr = linked_item.release();
    if (auto ref = ValueCast<Reference>(linked_item_ptr)) {
      return std::unique_ptr<Reference>(ref);
    }
    context_->GetDiagnostics()->Error(android::DiagMessage(value->GetSource())
                                      << "value of '"
                                      << LoggingResourceName(*value, callsite_, package_decls_)
                                      << "' must be a resource reference");
    delete linked_item_ptr;
  }

  error_ = true;
  return CloningValueTransformer::TransformDerived(value);
}

std::unique_ptr<Style> ReferenceLinkerTransformer::TransformDerived(const Style* style) {
  // We visit the Style specially because during this phase, values of attributes are either
  // RawString or Reference values. Now that we are expected to resolve all symbols, we can lookup
  // the attributes to find out which types are allowed for the attributes' values.
  auto new_style = CloningValueTransformer::TransformDerived(style);
  if (new_style->parent) {
    new_style->parent = *TransformDerived(&style->parent.value());
  }

  for (Style::Entry& entry : new_style->entries) {
    std::string err_str;

    // Transform the attribute reference so that it is using the fully qualified package
    // name. This will also mark the reference as being able to see private resources if
    // there was a '*' in the reference or if the package came from the private namespace.
    Reference transformed_reference = entry.key;
    ResolvePackage(package_decls_, &transformed_reference);

    // Find the attribute in the symbol table and check if it is visible from this callsite.
    const SymbolTable::Symbol* symbol = ReferenceLinker::ResolveAttributeCheckVisibility(
        transformed_reference, callsite_, context_, symbols_, &err_str);
    if (symbol) {
      // Assign our style key the correct ID. The ID may not exist.
      entry.key.id = symbol->id;

      // Link/resolve the final value if it's a reference.
      entry.value = entry.value->Transform(*this);

      // Try to convert the value to a more specific, typed value based on the attribute it is
      // set to.
      entry.value = ParseValueWithAttribute(std::move(entry.value), symbol->attribute.get());

      // Now verify that the type of this item is compatible with the
      // attribute it is defined for. We pass `nullptr` as the DiagMessage so that this
      // check is fast and we avoid creating a DiagMessage when the match is successful.
      if (!symbol->attribute->Matches(*entry.value, nullptr)) {
        // The actual type of this item is incompatible with the attribute.
        android::DiagMessage msg(entry.key.GetSource());

        // Call the matches method again, this time with a DiagMessage so we fill in the actual
        // error message.
        symbol->attribute->Matches(*entry.value, &msg);
        context_->GetDiagnostics()->Error(msg);
        error_ = true;
      }
    } else {
      context_->GetDiagnostics()->Error(android::DiagMessage(entry.key.GetSource())
                                        << "style attribute '"
                                        << LoggingResourceName(entry.key, callsite_, package_decls_)
                                        << "' " << err_str);

      error_ = true;
    }
  }
  return new_style;
}

std::unique_ptr<Item> ReferenceLinkerTransformer::TransformItem(const Reference* value) {
  auto linked_value =
      ReferenceLinker::LinkReference(callsite_, *value, context_, symbols_, table_, package_decls_);
  if (linked_value) {
    return linked_value;
  }
  error_ = true;
  return CloningValueTransformer::TransformDerived(value);
}

// Transform a RawString value into a more specific, appropriate value, based on the
// Attribute. If a non RawString value is passed in, this is an identity transform.
std::unique_ptr<Item> ReferenceLinkerTransformer::ParseValueWithAttribute(
    std::unique_ptr<Item> value, const Attribute* attr) {
  if (RawString* raw_string = ValueCast<RawString>(value.get())) {
    std::unique_ptr<Item> transformed = ResourceUtils::TryParseItemForAttribute(
        context_->GetDiagnostics(), *raw_string->value, attr);

    // If we could not parse as any specific type, try a basic STRING.
    if (!transformed && (attr->type_mask & android::ResTable_map::TYPE_STRING)) {
      StringBuilder string_builder;
      string_builder.AppendText(*raw_string->value);
      if (string_builder) {
        transformed = util::make_unique<String>(pool_->MakeRef(string_builder.to_string()));
      }
    }

    if (transformed) {
      return transformed;
    }
  }
  return value;
}

namespace {

class EmptyDeclStack : public xml::IPackageDeclStack {
 public:
  EmptyDeclStack() = default;

  std::optional<xml::ExtractedPackage> TransformPackageAlias(StringPiece alias) const override {
    if (alias.empty()) {
      return xml::ExtractedPackage{{}, true /*private*/};
    }
    return {};
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EmptyDeclStack);
};

struct MacroDeclStack : public xml::IPackageDeclStack {
  explicit MacroDeclStack(std::vector<Macro::Namespace> namespaces)
      : alias_namespaces_(std::move(namespaces)) {
  }

  std::optional<xml::ExtractedPackage> TransformPackageAlias(StringPiece alias) const override {
    if (alias.empty()) {
      return xml::ExtractedPackage{{}, true /*private*/};
    }
    for (auto it = alias_namespaces_.rbegin(); it != alias_namespaces_.rend(); ++it) {
      if (alias == StringPiece(it->alias)) {
        return xml::ExtractedPackage{it->package_name, it->is_private};
      }
    }
    return {};
  }

 private:
  std::vector<Macro::Namespace> alias_namespaces_;
};

// The symbol is visible if it is public, or if the reference to it is requesting private access
// or if the callsite comes from the same package.
bool IsSymbolVisible(const SymbolTable::Symbol& symbol, const Reference& ref,
                     const CallSite& callsite) {
  if (symbol.is_public || ref.private_reference) {
    return true;
  }

  if (ref.name) {
    const ResourceName& name = ref.name.value();
    if (name.package.empty()) {
      // If the symbol was found, and the package is empty, that means it was found in the local
      // scope, which is always visible (private local).
      return true;
    }

    // The symbol is visible if the reference is local to the same package it is defined in.
    return callsite.package == name.package;
  }

  if (ref.id && symbol.id) {
    return ref.id.value().package_id() == symbol.id.value().package_id();
  }
  return false;
}

}  // namespace

const SymbolTable::Symbol* ReferenceLinker::ResolveSymbol(const Reference& reference,
                                                          const CallSite& callsite,
                                                          IAaptContext* context,
                                                          SymbolTable* symbols) {
  if (reference.name) {
    const ResourceName& name = reference.name.value();
    if (name.package.empty()) {
      // Use the callsite's package name if no package name was defined.
      const SymbolTable::Symbol* symbol = symbols->FindByName(
          ResourceName(callsite.package, name.type, name.entry));
      if (symbol) {
        return symbol;
      }

      // If the callsite package is the same as the current compilation package,
      // check the feature split dependencies as well. Feature split resources
      // can be referenced without a namespace, just like the base package.
      if (callsite.package == context->GetCompilationPackage()) {
        const auto& split_name_dependencies = context->GetSplitNameDependencies();
        for (const std::string& split_name : split_name_dependencies) {
          std::string split_package =
              StringPrintf("%s.%s", callsite.package.c_str(), split_name.c_str());
          symbol = symbols->FindByName(ResourceName(split_package, name.type, name.entry));
          if (symbol) {
            return symbol;
          }
        }
      }
      return nullptr;
    }
    return symbols->FindByName(name);
  } else if (reference.id) {
    return symbols->FindById(reference.id.value());
  } else {
    return nullptr;
  }
}

const SymbolTable::Symbol* ReferenceLinker::ResolveSymbolCheckVisibility(const Reference& reference,
                                                                         const CallSite& callsite,
                                                                         IAaptContext* context,
                                                                         SymbolTable* symbols,
                                                                         std::string* out_error) {
  const SymbolTable::Symbol* symbol = ResolveSymbol(reference, callsite, context, symbols);
  if (!symbol) {
    if (out_error) *out_error = "not found";
    return nullptr;
  }

  if (!IsSymbolVisible(*symbol, reference, callsite)) {
    if (out_error) *out_error = "is private";
    return nullptr;
  }
  return symbol;
}

const SymbolTable::Symbol* ReferenceLinker::ResolveAttributeCheckVisibility(
    const Reference& reference, const CallSite& callsite, IAaptContext* context,
    SymbolTable* symbols, std::string* out_error) {
  const SymbolTable::Symbol* symbol =
      ResolveSymbolCheckVisibility(reference, callsite, context, symbols, out_error);
  if (!symbol) {
    return nullptr;
  }

  if (!symbol->attribute) {
    if (out_error) *out_error = "is not an attribute";
    return nullptr;
  }
  return symbol;
}

std::optional<xml::AaptAttribute> ReferenceLinker::CompileXmlAttribute(const Reference& reference,
                                                                       const CallSite& callsite,
                                                                       IAaptContext* context,
                                                                       SymbolTable* symbols,
                                                                       std::string* out_error) {
  const SymbolTable::Symbol* symbol =
      ResolveAttributeCheckVisibility(reference, callsite, context, symbols, out_error);
  if (!symbol) {
    return {};
  }

  if (!symbol->attribute) {
    if (out_error) *out_error = "is not an attribute";
    return {};
  }
  return xml::AaptAttribute(*symbol->attribute, symbol->id);
}

void ReferenceLinker::WriteAttributeName(const Reference& ref, const CallSite& callsite,
                                         const xml::IPackageDeclStack* decls,
                                         android::DiagMessage* out_msg) {
  CHECK(out_msg != nullptr);
  if (!ref.name) {
    *out_msg << ref.id.value();
    return;
  }

  const ResourceName& ref_name = ref.name.value();
  CHECK_EQ(ref_name.type.type, ResourceType::kAttr);

  if (!ref_name.package.empty()) {
    *out_msg << ref_name.package << ":";
  }
  *out_msg << ref_name.entry;

  Reference fully_qualified = ref;
  xml::ResolvePackage(decls, &fully_qualified);

  ResourceName& full_name = fully_qualified.name.value();
  if (full_name.package.empty()) {
    full_name.package = callsite.package;
  }

  if (full_name != ref.name.value()) {
    *out_msg << " (aka " << full_name.package << ":" << full_name.entry << ")";
  }
}

std::unique_ptr<Item> ReferenceLinker::LinkReference(const CallSite& callsite,
                                                     const Reference& reference,
                                                     IAaptContext* context, SymbolTable* symbols,
                                                     ResourceTable* table,
                                                     const xml::IPackageDeclStack* decls) {
  if (!reference.name && !reference.id) {
    // This is @null.
    return std::make_unique<Reference>(reference);
  }

  Reference transformed_reference = reference;
  xml::ResolvePackage(decls, &transformed_reference);

  if (transformed_reference.name.value().type.type == ResourceType::kMacro) {
    if (transformed_reference.name.value().package.empty()) {
      transformed_reference.name.value().package = callsite.package;
    }

    auto result = table->FindResource(transformed_reference.name.value());
    if (!result || result.value().entry->values.empty()) {
      context->GetDiagnostics()->Error(
          android::DiagMessage(reference.GetSource())
          << "failed to find definition for "
          << LoggingResourceName(transformed_reference, callsite, decls));
      return {};
    }

    auto& macro_values = result.value().entry->values;
    CHECK(macro_values.size() == 1) << "Macros can only be defined in the default configuration.";

    auto macro = ValueCast<Macro>(macro_values[0]->value.get());
    CHECK(macro != nullptr) << "Value of macro resource is not a Macro (actual "
                            << *macro_values[0]->value << ")";

    // Re-create the state used to parse the macro tag to compile the macro contents as if it was
    // defined inline
    uint32_t type_flags = 0;
    if (reference.type_flags.has_value()) {
      type_flags = reference.type_flags.value();
    }

    MacroDeclStack namespace_stack(macro->alias_namespaces);
    FlattenedXmlSubTree sub_tree{.raw_value = macro->raw_value,
                                 .style_string = macro->style_string,
                                 .untranslatable_sections = macro->untranslatable_sections,
                                 .namespace_resolver = &namespace_stack,
                                 .source = macro->GetSource()};

    auto new_value = ResourceParser::ParseXml(sub_tree, type_flags, reference.allow_raw, *table,
                                              macro_values[0]->config, *context->GetDiagnostics());
    if (new_value == nullptr) {
      context->GetDiagnostics()->Error(
          android::DiagMessage(reference.GetSource())
          << "failed to substitute macro "
          << LoggingResourceName(transformed_reference, callsite, decls)
          << ": failed to parse contents as one of type(s) " << Attribute::MaskString(type_flags));
      return {};
    }

    if (auto ref = ValueCast<Reference>(new_value.get())) {
      return LinkReference(callsite, *ref, context, symbols, table, decls);
    }
    return new_value;
  }

  std::string err_str;
  const SymbolTable::Symbol* s =
      ResolveSymbolCheckVisibility(transformed_reference, callsite, context, symbols, &err_str);
  if (s) {
    // The ID may not exist. This is fine because of the possibility of building
    // against libraries without assigned IDs.
    // Ex: Linking against own resources when building a static library.
    auto new_ref = std::make_unique<Reference>(reference);
    new_ref->id = s->id;
    new_ref->is_dynamic = s->is_dynamic;
    return std::move(new_ref);
  }

  context->GetDiagnostics()->Error(android::DiagMessage(reference.GetSource())
                                   << "resource "
                                   << LoggingResourceName(transformed_reference, callsite, decls)
                                   << " " << err_str);
  return {};
}

bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) {
  TRACE_NAME("ReferenceLinker::Consume");
  EmptyDeclStack decl_stack;
  bool error = false;
  for (auto& package : table->packages) {
    // Since we're linking, each package must have a name.
    CHECK(!package->name.empty()) << "all packages being linked must have a name";

    for (auto& type : package->types) {
      for (auto& entry : type->entries) {
        // First, unmangle the name if necessary.
        ResourceName name(package->name, type->named_type, entry->name);
        NameMangler::Unmangle(&name.entry, &name.package);

        // Symbol state information may be lost if there is no value for the resource.
        if (entry->visibility.level != Visibility::Level::kUndefined && entry->values.empty()) {
          context->GetDiagnostics()->Error(android::DiagMessage(entry->visibility.source)
                                           << "no definition for declared symbol '" << name << "'");
          error = true;
        }

        // Ensure that definitions for values declared as overlayable exist
        if (entry->overlayable_item && entry->values.empty()) {
          context->GetDiagnostics()->Error(
              android::DiagMessage(entry->overlayable_item.value().source)
              << "no definition for overlayable symbol '" << name << "'");
          error = true;
        }

        // The context of this resource is the package in which it is defined.
        const CallSite callsite{name.package};
        ReferenceLinkerTransformer reference_transformer(callsite, context,
                                                         context->GetExternalSymbols(),
                                                         &table->string_pool, table, &decl_stack);

        for (auto& config_value : entry->values) {
          config_value->value = config_value->value->Transform(reference_transformer);
        }

        if (reference_transformer.HasError()) {
          error = true;
        }
      }
    }
  }
  return !error;
}

}  // namespace aapt
