/*
 * 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.
 */

#ifndef AAPT_RESOURCE_VALUES_H
#define AAPT_RESOURCE_VALUES_H

#include <array>
#include <limits>
#include <ostream>
#include <vector>

#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"

#include "Diagnostics.h"
#include "Resource.h"
#include "StringPool.h"
#include "ValueTransformer.h"
#include "io/File.h"
#include "text/Printer.h"
#include "util/Maybe.h"

namespace aapt {

class ValueVisitor;
class ConstValueVisitor;

// A resource value. This is an all-encompassing representation
// of Item and Map and their subclasses. The way to do
// type specific operations is to check the Value's type() and
// cast it to the appropriate subclass. This isn't super clean,
// but it is the simplest strategy.
class Value {
 public:
  virtual ~Value() = default;

  // Whether this value is weak and can be overridden without warning or error. Default is false.
  bool IsWeak() const {
    return weak_;
  }

  void SetWeak(bool val) {
    weak_ = val;
  }

  // Whether the value is marked as translatable. This does not persist when flattened to binary.
  // It is only used during compilation phase.
  void SetTranslatable(bool val) {
    translatable_ = val;
  }

  // Default true.
  bool IsTranslatable() const {
    return translatable_;
  }

  // Returns the source where this value was defined.
  const Source& GetSource() const {
    return source_;
  }

  void SetSource(const Source& source) {
    source_ = source;
  }

  void SetSource(Source&& source) {
    source_ = std::move(source);
  }

  // Returns the comment that was associated with this resource.
  const std::string& GetComment() const {
    return comment_;
  }

  void SetComment(const android::StringPiece& str) {
    comment_ = str.to_string();
  }

  void SetComment(std::string&& str) {
    comment_ = std::move(str);
  }

  virtual bool Equals(const Value* value) const = 0;

  // Calls the appropriate overload of ValueVisitor.
  virtual void Accept(ValueVisitor* visitor) = 0;

  // Calls the appropriate overload of ConstValueVisitor.
  virtual void Accept(ConstValueVisitor* visitor) const = 0;

  // Transform this Value into another Value using the transformer.
  std::unique_ptr<Value> Transform(ValueTransformer& transformer) const;

  // Human readable printout of this value.
  virtual void Print(std::ostream* out) const = 0;

  // Human readable printout of this value that may omit some information for the sake
  // of brevity and readability. Default implementation just calls Print().
  virtual void PrettyPrint(text::Printer* printer) const;

  friend std::ostream& operator<<(std::ostream& out, const Value& value);

 protected:
  Source source_;
  std::string comment_;
  bool weak_ = false;
  bool translatable_ = true;

 private:
  virtual Value* TransformValueImpl(ValueTransformer& transformer) const = 0;
};

// Inherit from this to get visitor accepting implementations for free.
template <typename Derived>
struct BaseValue : public Value {
  void Accept(ValueVisitor* visitor) override;
  void Accept(ConstValueVisitor* visitor) const override;
};

// A resource item with a single value. This maps to android::ResTable_entry.
struct Item : public Value {
  // Fills in an android::Res_value structure with this Item's binary representation.
  // Returns false if an error occurred.
  virtual bool Flatten(android::Res_value* out_value) const = 0;

  // Transform this Item into another Item using the transformer.
  std::unique_ptr<Item> Transform(ValueTransformer& transformer) const;

 private:
  virtual Item* TransformItemImpl(ValueTransformer& transformer) const = 0;
};

// Inherit from this to get visitor accepting implementations for free.
template <typename Derived>
struct BaseItem : public Item {
  void Accept(ValueVisitor* visitor) override;
  void Accept(ConstValueVisitor* visitor) const override;
};

// A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
// A reference can be symbolic (with the name set to a valid resource name) or be
// numeric (the id is set to a valid resource ID).
struct Reference : public TransformableItem<Reference, BaseItem<Reference>> {
  enum class Type : uint8_t {
    kResource,
    kAttribute,
  };

  Maybe<ResourceName> name;
  Maybe<ResourceId> id;
  std::optional<uint32_t> type_flags;
  Reference::Type reference_type;
  bool private_reference = false;
  bool is_dynamic = false;
  bool allow_raw = false;

  Reference();
  explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
  explicit Reference(const ResourceId& i, Type type = Type::kResource);
  Reference(const ResourceNameRef& n, const ResourceId& i);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
  void PrettyPrint(text::Printer* printer) const override;

  // Prints the reference without a package name if the package name matches the one given.
  void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const;
};

bool operator<(const Reference&, const Reference&);
bool operator==(const Reference&, const Reference&);

// An ID resource. Has no real value, just a place holder.
struct Id : public TransformableItem<Id, BaseItem<Id>> {
  Id() {
    weak_ = true;
  }

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out) const override;
  void Print(std::ostream* out) const override;
};

// A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace.
// This shall *NOT* end up in the final resource table.
struct RawString : public TransformableItem<RawString, BaseItem<RawString>> {
  StringPool::Ref value;

  explicit RawString(const StringPool::Ref& ref);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
};

// Identifies a range of characters in a string that are untranslatable.
// These should not be pseudolocalized. The start and end indices are measured in bytes.
struct UntranslatableSection {
  // Start offset inclusive.
  size_t start;

  // End offset exclusive.
  size_t end;
};

inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) {
  return a.start == b.start && a.end == b.end;
}

inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) {
  return a.start != b.start || a.end != b.end;
}

struct String : public TransformableItem<String, BaseItem<String>> {
  StringPool::Ref value;

  // Sections of the string to NOT translate. Mainly used
  // for pseudolocalization. This data is NOT persisted
  // in any format.
  std::vector<UntranslatableSection> untranslatable_sections;

  explicit String(const StringPool::Ref& ref);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
  void PrettyPrint(text::Printer* printer) const override;
};

struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> {
  StringPool::StyleRef value;

  // Sections of the string to NOT translate. Mainly used
  // for pseudolocalization. This data is NOT persisted
  // in any format.
  std::vector<UntranslatableSection> untranslatable_sections;

  explicit StyledString(const StringPool::StyleRef& ref);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
};

struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> {
  StringPool::Ref path;

  // A handle to the file object from which this file can be read.
  // This field is NOT persisted in any format. It is transient.
  io::IFile* file = nullptr;

  // FileType of the file pointed to by `file`. This is used to know how to inflate the file,
  // or if to inflate at all (just copy).
  ResourceFile::Type type = ResourceFile::Type::kUnknown;

  FileReference() = default;
  explicit FileReference(const StringPool::Ref& path);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
};

// Represents any other android::Res_value.
struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<BinaryPrimitive>> {
  android::Res_value value;

  BinaryPrimitive() = default;
  explicit BinaryPrimitive(const android::Res_value& val);
  BinaryPrimitive(uint8_t dataType, uint32_t data);

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
  void PrettyPrint(text::Printer* printer) const override;
};

struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> {
  struct Symbol {
    Reference symbol;
    uint32_t value;
    uint8_t type;

    friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
  };

  uint32_t type_mask;
  int32_t min_int;
  int32_t max_int;
  std::vector<Symbol> symbols;

  explicit Attribute(uint32_t t = 0u);

  bool Equals(const Value* value) const override;

  // Returns true if this Attribute's format is compatible with the given Attribute. The basic
  // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and
  // TYPE_ENUMS are never compatible.
  bool IsCompatibleWith(const Attribute& attr) const;

  std::string MaskString() const;
  static std::string MaskString(uint32_t type_mask);

  void Print(std::ostream* out) const override;
  bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const;
};

struct Style : public TransformableValue<Style, BaseValue<Style>> {
  struct Entry {
    Reference key;
    std::unique_ptr<Item> value;

    friend std::ostream& operator<<(std::ostream& out, const Entry& entry);
  };

  Maybe<Reference> parent;

  // If set to true, the parent was auto inferred from the style's name.
  bool parent_inferred = false;

  std::vector<Entry> entries;

  bool Equals(const Value* value) const override;
  void Print(std::ostream* out) const override;

  // Merges `style` into this Style. All identical attributes of `style` take precedence, including
  // the parent, if there is one.
  void MergeWith(Style* style, StringPool* pool);
};

struct Array : public TransformableValue<Array, BaseValue<Array>> {
  std::vector<std::unique_ptr<Item>> elements;

  bool Equals(const Value* value) const override;
  void Print(std::ostream* out) const override;
};

struct Plural : public TransformableValue<Plural, BaseValue<Plural>> {
  enum { Zero = 0, One, Two, Few, Many, Other, Count };

  std::array<std::unique_ptr<Item>, Count> values;

  bool Equals(const Value* value) const override;
  void Print(std::ostream* out) const override;
};

struct Styleable : public TransformableValue<Styleable, BaseValue<Styleable>> {
  std::vector<Reference> entries;

  bool Equals(const Value* value) const override;
  void Print(std::ostream* out) const override;
  void MergeWith(Styleable* styleable);
};

struct Macro : public TransformableValue<Macro, BaseValue<Macro>> {
  std::string raw_value;
  StyleString style_string;
  std::vector<UntranslatableSection> untranslatable_sections;

  struct Namespace {
    std::string alias;
    std::string package_name;
    bool is_private;

    bool operator==(const Namespace& right) const {
      return alias == right.alias && package_name == right.package_name &&
             is_private == right.is_private;
    }
  };

  std::vector<Namespace> alias_namespaces;

  bool Equals(const Value* value) const override;
  void Print(std::ostream* out) const override;
};

template <typename T>
typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
    std::ostream& out, const std::unique_ptr<T>& value) {
  if (value == nullptr) {
    out << "NULL";
  } else {
    value->Print(&out);
  }
  return out;
}

struct CloningValueTransformer : public ValueTransformer {
  explicit CloningValueTransformer(StringPool* new_pool);

  std::unique_ptr<Reference> TransformDerived(const Reference* value) override;
  std::unique_ptr<Id> TransformDerived(const Id* value) override;
  std::unique_ptr<RawString> TransformDerived(const RawString* value) override;
  std::unique_ptr<String> TransformDerived(const String* value) override;
  std::unique_ptr<StyledString> TransformDerived(const StyledString* value) override;
  std::unique_ptr<FileReference> TransformDerived(const FileReference* value) override;
  std::unique_ptr<BinaryPrimitive> TransformDerived(const BinaryPrimitive* value) override;
  std::unique_ptr<Attribute> TransformDerived(const Attribute* value) override;
  std::unique_ptr<Style> TransformDerived(const Style* value) override;
  std::unique_ptr<Array> TransformDerived(const Array* value) override;
  std::unique_ptr<Plural> TransformDerived(const Plural* value) override;
  std::unique_ptr<Styleable> TransformDerived(const Styleable* value) override;
  std::unique_ptr<Macro> TransformDerived(const Macro* value) override;
};

}  // namespace aapt

#endif  // AAPT_RESOURCE_VALUES_H
