/*
 * 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 "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"

#include "Diagnostics.h"
#include "ResourceParser.h"
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.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(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.
        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(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(*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;

  Maybe<xml::ExtractedPackage> TransformPackageAlias(const 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)) {
  }

  Maybe<xml::ExtractedPackage> TransformPackageAlias(const 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;
}

Maybe<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,
                                         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, 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 == 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(
          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(
          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(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->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(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(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
