/*
 * 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_VALUE_VISITOR_H
#define AAPT_VALUE_VISITOR_H

#include "ResourceTable.h"
#include "ResourceValues.h"

namespace aapt {

// Visits a value and invokes the appropriate method based on its type.
// Does not traverse into compound types. Use ValueVisitor for that.
class ValueVisitor {
 public:
  virtual ~ValueVisitor() = default;

  virtual void VisitAny(Value* value) {}
  virtual void VisitItem(Item* value) { VisitAny(value); }
  virtual void Visit(Reference* value) { VisitItem(value); }
  virtual void Visit(RawString* value) { VisitItem(value); }
  virtual void Visit(String* value) { VisitItem(value); }
  virtual void Visit(StyledString* value) { VisitItem(value); }
  virtual void Visit(FileReference* value) { VisitItem(value); }
  virtual void Visit(Id* value) { VisitItem(value); }
  virtual void Visit(BinaryPrimitive* value) { VisitItem(value); }

  virtual void Visit(Attribute* value) { VisitAny(value); }
  virtual void Visit(Style* value) { VisitAny(value); }
  virtual void Visit(Array* value) { VisitAny(value); }
  virtual void Visit(Plural* value) { VisitAny(value); }
  virtual void Visit(Styleable* value) { VisitAny(value); }
};

// Const version of ValueVisitor.
class ConstValueVisitor {
 public:
  virtual ~ConstValueVisitor() = default;

  virtual void VisitAny(const Value* value) {
  }
  virtual void VisitItem(const Item* value) {
    VisitAny(value);
  }
  virtual void Visit(const Reference* value) {
    VisitItem(value);
  }
  virtual void Visit(const RawString* value) {
    VisitItem(value);
  }
  virtual void Visit(const String* value) {
    VisitItem(value);
  }
  virtual void Visit(const StyledString* value) {
    VisitItem(value);
  }
  virtual void Visit(const FileReference* value) {
    VisitItem(value);
  }
  virtual void Visit(const Id* value) {
    VisitItem(value);
  }
  virtual void Visit(const BinaryPrimitive* value) {
    VisitItem(value);
  }

  virtual void Visit(const Attribute* value) {
    VisitAny(value);
  }
  virtual void Visit(const Style* value) {
    VisitAny(value);
  }
  virtual void Visit(const Array* value) {
    VisitAny(value);
  }
  virtual void Visit(const Plural* value) {
    VisitAny(value);
  }
  virtual void Visit(const Styleable* value) {
    VisitAny(value);
  }
};

// NOLINT, do not add parentheses around T.
#define DECL_VISIT_COMPOUND_VALUE(T)                   \
  virtual void Visit(T* value) override { /* NOLINT */ \
    VisitSubValues(value);                             \
  }

// Visits values, and if they are compound values, descends into their components as well.
struct DescendingValueVisitor : public ValueVisitor {
  // The compiler will think we're hiding an overload, when we actually intend
  // to call into RawValueVisitor. This will expose the visit methods in the
  // super class so the compiler knows we are trying to call them.
  using ValueVisitor::Visit;

  void VisitSubValues(Attribute* attribute) {
    for (Attribute::Symbol& symbol : attribute->symbols) {
      Visit(&symbol.symbol);
    }
  }

  void VisitSubValues(Style* style) {
    if (style->parent) {
      Visit(&style->parent.value());
    }

    for (Style::Entry& entry : style->entries) {
      Visit(&entry.key);
      entry.value->Accept(this);
    }
  }

  void VisitSubValues(Array* array) {
    for (std::unique_ptr<Item>& item : array->elements) {
      item->Accept(this);
    }
  }

  void VisitSubValues(Plural* plural) {
    for (std::unique_ptr<Item>& item : plural->values) {
      if (item) {
        item->Accept(this);
      }
    }
  }

  void VisitSubValues(Styleable* styleable) {
    for (Reference& reference : styleable->entries) {
      Visit(&reference);
    }
  }

  DECL_VISIT_COMPOUND_VALUE(Attribute);
  DECL_VISIT_COMPOUND_VALUE(Style);
  DECL_VISIT_COMPOUND_VALUE(Array);
  DECL_VISIT_COMPOUND_VALUE(Plural);
  DECL_VISIT_COMPOUND_VALUE(Styleable);
};

// Do not use directly. Helper struct for dyn_cast.
template <typename T>
struct DynCastVisitor : public ConstValueVisitor {
  const T* value = nullptr;

  void Visit(const T* v) override {
    value = v;
  }
};

// Specialization that checks if the value is an Item.
template <>
struct DynCastVisitor<Item> : public ConstValueVisitor {
  const Item* value = nullptr;

  void VisitItem(const Item* item) override {
    value = item;
  }
};

// Returns a valid pointer to T if the value is an instance of T. Returns nullptr if value is
// nullptr of if value is not an instance of T.
template <typename T>
const T* ValueCast(const Value* value) {
  if (!value) {
    return nullptr;
  }
  DynCastVisitor<T> visitor;
  value->Accept(&visitor);
  return visitor.value;
}

// Non-const version of ValueCast.
template <typename T>
T* ValueCast(Value* value) {
  return const_cast<T*>(ValueCast<T>(static_cast<const Value*>(value)));
}

inline void VisitAllValuesInPackage(ResourceTablePackage* pkg, ValueVisitor* visitor) {
  for (auto& type : pkg->types) {
    for (auto& entry : type->entries) {
      for (auto& config_value : entry->values) {
        config_value->value->Accept(visitor);
      }
    }
  }
}

inline void VisitAllValuesInTable(ResourceTable* table, ValueVisitor* visitor) {
  for (auto& pkg : table->packages) {
    VisitAllValuesInPackage(pkg.get(), visitor);
  }
}

}  // namespace aapt

#endif  // AAPT_VALUE_VISITOR_H
