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

#include <algorithm>
#include <cinttypes>
#include <limits>
#include <set>
#include <sstream>

#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"

#include "Resource.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
#include "util/Util.h"

using ::aapt::text::Printer;
using ::android::StringPiece;
using ::android::base::StringPrintf;

namespace aapt {

void Value::PrettyPrint(Printer* printer) const {
  std::ostringstream str_stream;
  Print(&str_stream);
  printer->Print(str_stream.str());
}

std::ostream& operator<<(std::ostream& out, const Value& value) {
  value.Print(&out);
  return out;
}

std::unique_ptr<Value> Value::Transform(ValueTransformer& transformer) const {
  return std::unique_ptr<Value>(this->TransformValueImpl(transformer));
}

std::unique_ptr<Item> Item::Transform(ValueTransformer& transformer) const {
  return std::unique_ptr<Item>(this->TransformItemImpl(transformer));
}

template <typename Derived>
void BaseValue<Derived>::Accept(ValueVisitor* visitor) {
  visitor->Visit(static_cast<Derived*>(this));
}

template <typename Derived>
void BaseValue<Derived>::Accept(ConstValueVisitor* visitor) const {
  visitor->Visit(static_cast<const Derived*>(this));
}

template <typename Derived>
void BaseItem<Derived>::Accept(ValueVisitor* visitor) {
  visitor->Visit(static_cast<Derived*>(this));
}

template <typename Derived>
void BaseItem<Derived>::Accept(ConstValueVisitor* visitor) const {
  visitor->Visit(static_cast<const Derived*>(this));
}

RawString::RawString(const android::StringPool::Ref& ref) : value(ref) {
}

bool RawString::Equals(const Value* value) const {
  const RawString* other = ValueCast<RawString>(value);
  if (!other) {
    return false;
  }
  return *this->value == *other->value;
}

bool RawString::Flatten(android::Res_value* out_value) const {
  out_value->dataType = android::Res_value::TYPE_STRING;
  out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
  return true;
}

void RawString::Print(std::ostream* out) const {
  *out << "(raw string) " << *value;
}

Reference::Reference() : reference_type(Type::kResource) {}

Reference::Reference(const ResourceNameRef& n, Type t)
    : name(n.ToResourceName()), reference_type(t) {}

Reference::Reference(const ResourceId& i, Type type)
    : id(i), reference_type(type) {}

Reference::Reference(const ResourceNameRef& n, const ResourceId& i)
    : name(n.ToResourceName()), id(i), reference_type(Type::kResource) {}

bool Reference::Equals(const Value* value) const {
  const Reference* other = ValueCast<Reference>(value);
  if (!other) {
    return false;
  }
  return reference_type == other->reference_type && private_reference == other->private_reference &&
         id == other->id && name == other->name && type_flags == other->type_flags;
}

bool Reference::Flatten(android::Res_value* out_value) const {
  if (name && name.value().type.type == ResourceType::kMacro) {
    return false;
  }

  const ResourceId resid = id.value_or(ResourceId(0));
  const bool dynamic = resid.is_valid() && is_dynamic;

  if (reference_type == Reference::Type::kResource) {
    if (dynamic) {
      out_value->dataType = android::Res_value::TYPE_DYNAMIC_REFERENCE;
    } else {
      out_value->dataType = android::Res_value::TYPE_REFERENCE;
    }
  } else {
    if (dynamic) {
      out_value->dataType = android::Res_value::TYPE_DYNAMIC_ATTRIBUTE;
    } else {
      out_value->dataType = android::Res_value::TYPE_ATTRIBUTE;
    }
  }
  out_value->data = android::util::HostToDevice32(resid.id);
  return true;
}

void Reference::Print(std::ostream* out) const {
  if (reference_type == Type::kResource) {
    *out << "(reference) @";
    if (!name && !id) {
      *out << "null";
      return;
    }
  } else {
    *out << "(attr-reference) ?";
  }

  if (private_reference) {
    *out << "*";
  }

  if (name) {
    *out << name.value();
  }

  if (id && id.value().is_valid()) {
    if (name) {
      *out << " ";
    }
    *out << id.value();
  }
}

static void PrettyPrintReferenceImpl(const Reference& ref, bool print_package, Printer* printer) {
  switch (ref.reference_type) {
    case Reference::Type::kResource:
      printer->Print("@");
      break;

    case Reference::Type::kAttribute:
      printer->Print("?");
      break;
  }

  if (!ref.name && !ref.id) {
    printer->Print("null");
    return;
  }

  if (ref.private_reference) {
    printer->Print("*");
  }

  if (ref.name) {
    const ResourceName& name = ref.name.value();
    if (print_package) {
      printer->Print(name.to_string());
    } else {
      printer->Print(name.type.to_string());
      printer->Print("/");
      printer->Print(name.entry);
    }
  } else if (ref.id && ref.id.value().is_valid()) {
    printer->Print(ref.id.value().to_string());
  }
}

void Reference::PrettyPrint(Printer* printer) const {
  PrettyPrintReferenceImpl(*this, true /*print_package*/, printer);
}

void Reference::PrettyPrint(StringPiece package, Printer* printer) const {
  const bool print_package = name ? package != name.value().package : true;
  PrettyPrintReferenceImpl(*this, print_package, printer);
}

bool Id::Equals(const Value* value) const {
  return ValueCast<Id>(value) != nullptr;
}

bool Id::Flatten(android::Res_value* out) const {
  out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
  out->data = android::util::HostToDevice32(0);
  return true;
}

void Id::Print(std::ostream* out) const {
  *out << "(id)";
}

String::String(const android::StringPool::Ref& ref) : value(ref) {
}

bool String::Equals(const Value* value) const {
  const String* other = ValueCast<String>(value);
  if (!other) {
    return false;
  }

  if (this->value != other->value) {
    return false;
  }

  if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    return false;
  }

  auto other_iter = other->untranslatable_sections.begin();
  for (const UntranslatableSection& this_section : untranslatable_sections) {
    if (this_section != *other_iter) {
      return false;
    }
    ++other_iter;
  }
  return true;
}

bool String::Flatten(android::Res_value* out_value) const {
  // Verify that our StringPool index is within encode-able limits.
  if (value.index() > std::numeric_limits<uint32_t>::max()) {
    return false;
  }

  out_value->dataType = android::Res_value::TYPE_STRING;
  out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
  return true;
}

void String::Print(std::ostream* out) const {
  *out << "(string) \"" << *value << "\"";
}

void String::PrettyPrint(Printer* printer) const {
  printer->Print("\"");
  printer->Print(*value);
  printer->Print("\"");
}

StyledString::StyledString(const android::StringPool::StyleRef& ref) : value(ref) {
}

bool StyledString::Equals(const Value* value) const {
  const StyledString* other = ValueCast<StyledString>(value);
  if (!other) {
    return false;
  }

  if (this->value != other->value) {
    return false;
  }

  if (untranslatable_sections.size() != other->untranslatable_sections.size()) {
    return false;
  }

  auto other_iter = other->untranslatable_sections.begin();
  for (const UntranslatableSection& this_section : untranslatable_sections) {
    if (this_section != *other_iter) {
      return false;
    }
    ++other_iter;
  }
  return true;
}

bool StyledString::Flatten(android::Res_value* out_value) const {
  if (value.index() > std::numeric_limits<uint32_t>::max()) {
    return false;
  }

  out_value->dataType = android::Res_value::TYPE_STRING;
  out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
  return true;
}

void StyledString::Print(std::ostream* out) const {
  *out << "(styled string) \"" << value->value << "\"";
  for (const android::StringPool::Span& span : value->spans) {
    *out << " " << *span.name << ":" << span.first_char << "," << span.last_char;
  }
}

FileReference::FileReference(const android::StringPool::Ref& _path) : path(_path) {
}

bool FileReference::Equals(const Value* value) const {
  const FileReference* other = ValueCast<FileReference>(value);
  if (!other) {
    return false;
  }
  return path == other->path;
}

bool FileReference::Flatten(android::Res_value* out_value) const {
  if (path.index() > std::numeric_limits<uint32_t>::max()) {
    return false;
  }

  out_value->dataType = android::Res_value::TYPE_STRING;
  out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(path.index()));
  return true;
}

void FileReference::Print(std::ostream* out) const {
  *out << "(file) " << *path;
  switch (type) {
    case ResourceFile::Type::kBinaryXml:
      *out << " type=XML";
      break;
    case ResourceFile::Type::kProtoXml:
      *out << " type=protoXML";
      break;
    case ResourceFile::Type::kPng:
      *out << " type=PNG";
      break;
    default:
      break;
  }
}

BinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {
}

BinaryPrimitive::BinaryPrimitive(uint8_t dataType, uint32_t data) {
  value.dataType = dataType;
  value.data = data;
}

bool BinaryPrimitive::Equals(const Value* value) const {
  const BinaryPrimitive* other = ValueCast<BinaryPrimitive>(value);
  if (!other) {
    return false;
  }
  return this->value.dataType == other->value.dataType &&
         this->value.data == other->value.data;
}

bool BinaryPrimitive::Flatten(::android::Res_value* out_value) const {
  out_value->dataType = value.dataType;
  out_value->data = android::util::HostToDevice32(value.data);
  return true;
}

void BinaryPrimitive::Print(std::ostream* out) const {
  *out << StringPrintf("(primitive) type=0x%02x data=0x%08x", value.dataType, value.data);
}

static std::string ComplexToString(uint32_t complex_value, bool fraction) {
  using ::android::Res_value;

  constexpr std::array<int, 4> kRadixShifts = {{23, 16, 8, 0}};

  // Determine the radix that was used.
  const uint32_t radix =
      (complex_value >> Res_value::COMPLEX_RADIX_SHIFT) & Res_value::COMPLEX_RADIX_MASK;
  const uint64_t mantissa = uint64_t{(complex_value >> Res_value::COMPLEX_MANTISSA_SHIFT) &
                                     Res_value::COMPLEX_MANTISSA_MASK}
                            << kRadixShifts[radix];
  const float value = mantissa * (1.0f / (1 << 23));

  std::string str = StringPrintf("%f", value);

  const int unit_type =
      (complex_value >> Res_value::COMPLEX_UNIT_SHIFT) & Res_value::COMPLEX_UNIT_MASK;
  if (fraction) {
    switch (unit_type) {
      case Res_value::COMPLEX_UNIT_FRACTION:
        str += "%";
        break;
      case Res_value::COMPLEX_UNIT_FRACTION_PARENT:
        str += "%p";
        break;
      default:
        str += "???";
        break;
    }
  } else {
    switch (unit_type) {
      case Res_value::COMPLEX_UNIT_PX:
        str += "px";
        break;
      case Res_value::COMPLEX_UNIT_DIP:
        str += "dp";
        break;
      case Res_value::COMPLEX_UNIT_SP:
        str += "sp";
        break;
      case Res_value::COMPLEX_UNIT_PT:
        str += "pt";
        break;
      case Res_value::COMPLEX_UNIT_IN:
        str += "in";
        break;
      case Res_value::COMPLEX_UNIT_MM:
        str += "mm";
        break;
      default:
        str += "???";
        break;
    }
  }
  return str;
}

void BinaryPrimitive::PrettyPrint(Printer* printer) const {
  using ::android::Res_value;
  switch (value.dataType) {
    case Res_value::TYPE_NULL:
      if (value.data == Res_value::DATA_NULL_EMPTY) {
        printer->Print("@empty");
      } else {
        printer->Print("@null");
      }
      break;

    case Res_value::TYPE_INT_DEC:
      printer->Print(StringPrintf("%" PRIi32, static_cast<int32_t>(value.data)));
      break;

    case Res_value::TYPE_INT_HEX:
      printer->Print(StringPrintf("0x%08x", value.data));
      break;

    case Res_value::TYPE_INT_BOOLEAN:
      printer->Print(value.data != 0 ? "true" : "false");
      break;

    case Res_value::TYPE_INT_COLOR_ARGB8:
    case Res_value::TYPE_INT_COLOR_RGB8:
    case Res_value::TYPE_INT_COLOR_ARGB4:
    case Res_value::TYPE_INT_COLOR_RGB4:
      printer->Print(StringPrintf("#%08x", value.data));
      break;

    case Res_value::TYPE_FLOAT:
      printer->Print(StringPrintf("%g", *reinterpret_cast<const float*>(&value.data)));
      break;

    case Res_value::TYPE_DIMENSION:
      printer->Print(ComplexToString(value.data, false /*fraction*/));
      break;

    case Res_value::TYPE_FRACTION:
      printer->Print(ComplexToString(value.data, true /*fraction*/));
      break;

    default:
      printer->Print(StringPrintf("(unknown 0x%02x) 0x%08x", value.dataType, value.data));
      break;
  }
}

Attribute::Attribute(uint32_t t)
    : type_mask(t),
      min_int(std::numeric_limits<int32_t>::min()),
      max_int(std::numeric_limits<int32_t>::max()) {
}

std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) {
  if (s.symbol.name) {
    out << s.symbol.name.value().entry;
  } else {
    out << "???";
  }
  return out << "=" << s.value;
}

template <typename T>
constexpr T* add_pointer(T& val) {
  return &val;
}

bool Attribute::Equals(const Value* value) const {
  const Attribute* other = ValueCast<Attribute>(value);
  if (!other) {
    return false;
  }

  if (symbols.size() != other->symbols.size()) {
    return false;
  }

  if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) {
    return false;
  }

  std::vector<const Symbol*> sorted_a;
  std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
                 add_pointer<const Symbol>);
  std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool {
    return a->symbol.name < b->symbol.name;
  });

  std::vector<const Symbol*> sorted_b;
  std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b),
                 add_pointer<const Symbol>);
  std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool {
    return a->symbol.name < b->symbol.name;
  });

  return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                    [](const Symbol* a, const Symbol* b) -> bool {
                      return a->symbol.Equals(&b->symbol) && a->value == b->value;
                    });
}

bool Attribute::IsCompatibleWith(const Attribute& attr) const {
  // If the high bits are set on any of these attribute type masks, then they are incompatible.
  // We don't check that flags and enums are identical.
  if ((type_mask & ~android::ResTable_map::TYPE_ANY) != 0 ||
      (attr.type_mask & ~android::ResTable_map::TYPE_ANY) != 0) {
    return false;
  }

  // Every attribute accepts a reference.
  uint32_t this_type_mask = type_mask | android::ResTable_map::TYPE_REFERENCE;
  uint32_t that_type_mask = attr.type_mask | android::ResTable_map::TYPE_REFERENCE;
  return this_type_mask == that_type_mask;
}

std::string Attribute::MaskString(uint32_t type_mask) {
  if (type_mask == android::ResTable_map::TYPE_ANY) {
    return "any";
  }

  std::ostringstream out;
  bool set = false;
  if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "reference";
  }

  if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "string";
  }

  if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "integer";
  }

  if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "boolean";
  }

  if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "color";
  }

  if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "float";
  }

  if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "dimension";
  }

  if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "fraction";
  }

  if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "enum";
  }

  if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) {
    if (!set) {
      set = true;
    } else {
      out << "|";
    }
    out << "flags";
  }
  return out.str();
}

std::string Attribute::MaskString() const {
  return MaskString(type_mask);
}

void Attribute::Print(std::ostream* out) const {
  *out << "(attr) " << MaskString();

  if (!symbols.empty()) {
    *out << " [" << util::Joiner(symbols, ", ") << "]";
  }

  if (min_int != std::numeric_limits<int32_t>::min()) {
    *out << " min=" << min_int;
  }

  if (max_int != std::numeric_limits<int32_t>::max()) {
    *out << " max=" << max_int;
  }

  if (IsWeak()) {
    *out << " [weak]";
  }
}

static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& value,
                                          android::DiagMessage* out_msg) {
  *out_msg << "expected";
  if (attr.type_mask & android::ResTable_map::TYPE_BOOLEAN) {
    *out_msg << " boolean";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_COLOR) {
    *out_msg << " color";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_DIMENSION) {
    *out_msg << " dimension";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_ENUM) {
    *out_msg << " enum";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_FLAGS) {
    *out_msg << " flags";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_FLOAT) {
    *out_msg << " float";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_FRACTION) {
    *out_msg << " fraction";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_INTEGER) {
    *out_msg << " integer";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_REFERENCE) {
    *out_msg << " reference";
  }

  if (attr.type_mask & android::ResTable_map::TYPE_STRING) {
    *out_msg << " string";
  }

  *out_msg << " but got " << value;
}

bool Attribute::Matches(const Item& item, android::DiagMessage* out_msg) const {
  constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
  constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
  constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
  constexpr const uint32_t TYPE_REFERENCE = android::ResTable_map::TYPE_REFERENCE;

  android::Res_value val = {};
  item.Flatten(&val);

  const uint32_t flattened_data = android::util::DeviceToHost32(val.data);

  // Always allow references.
  const uint32_t actual_type = ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType);

  // Only one type must match between the actual and expected.
  if ((actual_type & (type_mask | TYPE_REFERENCE)) == 0) {
    if (out_msg) {
      BuildAttributeMismatchMessage(*this, item, out_msg);
    }
    return false;
  }

  // Enums and flags are encoded as integers, so check them first before doing any range checks.
  if ((type_mask & TYPE_ENUM) != 0 && (actual_type & TYPE_ENUM) != 0) {
    for (const Symbol& s : symbols) {
      if (flattened_data == s.value) {
        return true;
      }
    }

    // If the attribute accepts integers, we can't fail here.
    if ((type_mask & TYPE_INTEGER) == 0) {
      if (out_msg) {
        *out_msg << item << " is not a valid enum";
      }
      return false;
    }
  }

  if ((type_mask & TYPE_FLAGS) != 0 && (actual_type & TYPE_FLAGS) != 0) {
    uint32_t mask = 0u;
    for (const Symbol& s : symbols) {
      mask |= s.value;
    }

    // Check if the flattened data is covered by the flag bit mask.
    // If the attribute accepts integers, we can't fail here.
    if ((mask & flattened_data) == flattened_data) {
      return true;
    } else if ((type_mask & TYPE_INTEGER) == 0) {
      if (out_msg) {
        *out_msg << item << " is not a valid flag";
      }
      return false;
    }
  }

  // Finally check the integer range of the value.
  if ((type_mask & TYPE_INTEGER) != 0 && (actual_type & TYPE_INTEGER) != 0) {
    if (static_cast<int32_t>(flattened_data) < min_int) {
      if (out_msg) {
        *out_msg << item << " is less than minimum integer " << min_int;
      }
      return false;
    } else if (static_cast<int32_t>(flattened_data) > max_int) {
      if (out_msg) {
        *out_msg << item << " is greater than maximum integer " << max_int;
      }
      return false;
    }
  }
  return true;
}

std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
  if (entry.key.name) {
    out << entry.key.name.value();
  } else if (entry.key.id) {
    out << entry.key.id.value();
  } else {
    out << "???";
  }
  out << " = " << entry.value;
  return out;
}

template <typename T>
std::vector<T*> ToPointerVec(std::vector<T>& src) {
  std::vector<T*> dst;
  dst.reserve(src.size());
  for (T& in : src) {
    dst.push_back(&in);
  }
  return dst;
}

template <typename T>
std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
  std::vector<const T*> dst;
  dst.reserve(src.size());
  for (const T& in : src) {
    dst.push_back(&in);
  }
  return dst;
}

static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
  return a->key.name < b->key.name;
}

bool Style::Equals(const Value* value) const {
  const Style* other = ValueCast<Style>(value);
  if (!other) {
    return false;
  }

  if (bool(parent) != bool(other->parent) ||
      (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
    return false;
  }

  if (entries.size() != other->entries.size()) {
    return false;
  }

  std::vector<const Entry*> sorted_a = ToPointerVec(entries);
  std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);

  std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
  std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);

  return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                    [](const Entry* a, const Entry* b) -> bool {
                      return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
                    });
}

void Style::Print(std::ostream* out) const {
  *out << "(style) ";
  if (parent && parent.value().name) {
    const Reference& parent_ref = parent.value();
    if (parent_ref.private_reference) {
      *out << "*";
    }
    *out << parent_ref.name.value();
  }
  *out << " [" << util::Joiner(entries, ", ") << "]";
}

Style::Entry CloneEntry(const Style::Entry& entry, android::StringPool* pool) {
  Style::Entry cloned_entry{entry.key};
  if (entry.value != nullptr) {
    CloningValueTransformer cloner(pool);
    cloned_entry.value = entry.value->Transform(cloner);
  }
  return cloned_entry;
}

void Style::MergeWith(Style* other, android::StringPool* pool) {
  if (other->parent) {
    parent = other->parent;
  }

  // We can't assume that the entries are sorted alphabetically since they're supposed to be
  // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
  // them keying off that.
  //
  // Instead, sort the entries of each Style by their name in a separate structure. Then merge
  // those.

  std::vector<Entry*> this_sorted = ToPointerVec(entries);
  std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);

  std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
  std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);

  auto this_iter = this_sorted.begin();
  const auto this_end = this_sorted.end();

  auto other_iter = other_sorted.begin();
  const auto other_end = other_sorted.end();

  std::vector<Entry> merged_entries;
  while (this_iter != this_end) {
    if (other_iter != other_end) {
      if ((*this_iter)->key.name < (*other_iter)->key.name) {
        merged_entries.push_back(std::move(**this_iter));
        ++this_iter;
      } else {
        // The other overrides.
        merged_entries.push_back(CloneEntry(**other_iter, pool));
        if ((*this_iter)->key.name == (*other_iter)->key.name) {
          ++this_iter;
        }
        ++other_iter;
      }
    } else {
      merged_entries.push_back(std::move(**this_iter));
      ++this_iter;
    }
  }

  while (other_iter != other_end) {
    merged_entries.push_back(CloneEntry(**other_iter, pool));
    ++other_iter;
  }

  entries = std::move(merged_entries);
}

bool Array::Equals(const Value* value) const {
  const Array* other = ValueCast<Array>(value);
  if (!other) {
    return false;
  }

  if (elements.size() != other->elements.size()) {
    return false;
  }

  return std::equal(elements.begin(), elements.end(), other->elements.begin(),
                    [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
                      return a->Equals(b.get());
                    });
}

void Array::Print(std::ostream* out) const {
  *out << "(array) [" << util::Joiner(elements, ", ") << "]";
}

bool Plural::Equals(const Value* value) const {
  const Plural* other = ValueCast<Plural>(value);
  if (!other) {
    return false;
  }

  auto one_iter = values.begin();
  auto one_end_iter = values.end();
  auto two_iter = other->values.begin();
  for (; one_iter != one_end_iter; ++one_iter, ++two_iter) {
    const std::unique_ptr<Item>& a = *one_iter;
    const std::unique_ptr<Item>& b = *two_iter;
    if (a != nullptr && b != nullptr) {
      if (!a->Equals(b.get())) {
        return false;
      }
    } else if (a != b) {
      return false;
    }
  }
  return true;
}

void Plural::Print(std::ostream* out) const {
  *out << "(plural)";
  if (values[Zero]) {
    *out << " zero=" << *values[Zero];
  }

  if (values[One]) {
    *out << " one=" << *values[One];
  }

  if (values[Two]) {
    *out << " two=" << *values[Two];
  }

  if (values[Few]) {
    *out << " few=" << *values[Few];
  }

  if (values[Many]) {
    *out << " many=" << *values[Many];
  }

  if (values[Other]) {
    *out << " other=" << *values[Other];
  }
}

bool Styleable::Equals(const Value* value) const {
  const Styleable* other = ValueCast<Styleable>(value);
  if (!other) {
    return false;
  }

  if (entries.size() != other->entries.size()) {
    return false;
  }

  return std::equal(entries.begin(), entries.end(), other->entries.begin(),
                    [](const Reference& a, const Reference& b) -> bool {
                      return a.Equals(&b);
                    });
}

void Styleable::Print(std::ostream* out) const {
  *out << "(styleable) "
       << " [" << util::Joiner(entries, ", ") << "]";
}

bool Macro::Equals(const Value* value) const {
  const Macro* other = ValueCast<Macro>(value);
  if (!other) {
    return false;
  }
  return other->raw_value == raw_value && other->style_string.spans == style_string.spans &&
         other->style_string.str == style_string.str &&
         other->untranslatable_sections == untranslatable_sections &&
         other->alias_namespaces == alias_namespaces;
}

void Macro::Print(std::ostream* out) const {
  *out << "(macro) ";
}

bool operator<(const Reference& a, const Reference& b) {
  int cmp = a.name.value_or(ResourceName{}).compare(b.name.value_or(ResourceName{}));
  if (cmp != 0) return cmp < 0;
  return a.id < b.id;
}

bool operator==(const Reference& a, const Reference& b) {
  return a.name == b.name && a.id == b.id;
}

bool operator!=(const Reference& a, const Reference& b) {
  return a.name != b.name || a.id != b.id;
}

struct NameOnlyComparator {
  bool operator()(const Reference& a, const Reference& b) const {
    return a.name < b.name;
  }
};

void Styleable::MergeWith(Styleable* other) {
  // Compare only names, because some References may already have their IDs
  // assigned (framework IDs that don't change).
  std::set<Reference, NameOnlyComparator> references;
  references.insert(entries.begin(), entries.end());
  references.insert(other->entries.begin(), other->entries.end());
  entries.clear();
  entries.reserve(references.size());
  entries.insert(entries.end(), references.begin(), references.end());
}

template <typename T>
std::unique_ptr<T> CopyValueFields(std::unique_ptr<T> new_value, const T* value) {
  new_value->SetSource(value->GetSource());
  new_value->SetComment(value->GetComment());
  return new_value;
}

CloningValueTransformer::CloningValueTransformer(android::StringPool* new_pool)
    : ValueTransformer(new_pool) {
}

std::unique_ptr<Reference> CloningValueTransformer::TransformDerived(const Reference* value) {
  return std::make_unique<Reference>(*value);
}

std::unique_ptr<Id> CloningValueTransformer::TransformDerived(const Id* value) {
  return std::make_unique<Id>(*value);
}

std::unique_ptr<RawString> CloningValueTransformer::TransformDerived(const RawString* value) {
  auto new_value = std::make_unique<RawString>(pool_->MakeRef(value->value));
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<String> CloningValueTransformer::TransformDerived(const String* value) {
  auto new_value = std::make_unique<String>(pool_->MakeRef(value->value));
  new_value->untranslatable_sections = value->untranslatable_sections;
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<StyledString> CloningValueTransformer::TransformDerived(const StyledString* value) {
  auto new_value = std::make_unique<StyledString>(pool_->MakeRef(value->value));
  new_value->untranslatable_sections = value->untranslatable_sections;
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<FileReference> CloningValueTransformer::TransformDerived(
    const FileReference* value) {
  auto new_value = std::make_unique<FileReference>(pool_->MakeRef(value->path));
  new_value->file = value->file;
  new_value->type = value->type;
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<BinaryPrimitive> CloningValueTransformer::TransformDerived(
    const BinaryPrimitive* value) {
  return std::make_unique<BinaryPrimitive>(*value);
}

std::unique_ptr<Attribute> CloningValueTransformer::TransformDerived(const Attribute* value) {
  auto new_value = std::make_unique<Attribute>();
  new_value->type_mask = value->type_mask;
  new_value->min_int = value->min_int;
  new_value->max_int = value->max_int;
  for (const Attribute::Symbol& s : value->symbols) {
    new_value->symbols.emplace_back(Attribute::Symbol{
        .symbol = *s.symbol.Transform(*this),
        .value = s.value,
        .type = s.type,
    });
  }
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<Style> CloningValueTransformer::TransformDerived(const Style* value) {
  auto new_value = std::make_unique<Style>();
  new_value->parent = value->parent;
  new_value->parent_inferred = value->parent_inferred;
  for (auto& entry : value->entries) {
    new_value->entries.push_back(Style::Entry{entry.key, entry.value->Transform(*this)});
  }
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<Array> CloningValueTransformer::TransformDerived(const Array* value) {
  auto new_value = std::make_unique<Array>();
  for (auto& item : value->elements) {
    new_value->elements.emplace_back(item->Transform(*this));
  }
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<Plural> CloningValueTransformer::TransformDerived(const Plural* value) {
  auto new_value = std::make_unique<Plural>();
  const size_t count = value->values.size();
  for (size_t i = 0; i < count; i++) {
    if (value->values[i]) {
      new_value->values[i] = value->values[i]->Transform(*this);
    }
  }
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<Styleable> CloningValueTransformer::TransformDerived(const Styleable* value) {
  auto new_value = std::make_unique<Styleable>();
  for (const Reference& s : value->entries) {
    new_value->entries.emplace_back(*s.Transform(*this));
  }
  return CopyValueFields(std::move(new_value), value);
}

std::unique_ptr<Macro> CloningValueTransformer::TransformDerived(const Macro* value) {
  auto new_value = std::make_unique<Macro>(*value);
  return CopyValueFields(std::move(new_value), value);
}

}  // namespace aapt
