// Copyright 2017-2020 The Verible Authors.
//
// 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 VERIBLE_COMMON_UTIL_VECTOR_TREE_H_
#define VERIBLE_COMMON_UTIL_VECTOR_TREE_H_

#include <algorithm>
#include <iosfwd>  // IWYU pragma: keep
#include <utility>
#include <vector>

#include "common/util/container_proxy.h"
#include "common/util/iterator_range.h"
#include "common/util/logging.h"

namespace verible {

// VectorTree is a hierarchical representation of information.
// While it may be useful to maintain some invariant relationship between
// parents and children nodes, it is not required for this class.
// The traversal methods ApplyPreOrder/ApplyPostOrder could be used to
// maintain or verify parent-child invariants.
// The VectorTree class is itself also the same as the vector_tree_internally
// used node class; i.e. there is no separate node class.
//
// Example applications (with some parent-child invariant relationship):
//
// * Range interval tree -- A numeric range from [0:N] could be sub-divided
//   into smaller ranges [0:k], [k:N] for some 0 < k < N, or multiple
//   monotonically increasing k's.  This class is a generalization of an
//   interval tree concept.
//
// * Lexical tokens output -- some tokens could be further tokenized or
//   expanded, but the choice of view depends on consumer and application.
//   This can be useful for embedding snippets of one language within another;
//   further lexing/parsing of an unexpanded substring can be deferred.
//
// * Lexical token range partitions -- token sub-range partitioning is a
//   critical step in a formatting strategy; the decision to partition
//   a particular range may be difficult to determine statically, so it
//   is best left undecided until a later heuristic pass.
//
// Construction:
// This implementation gives the user the liberty to construct the tree
// nodes in any order and any manner.  A top-down construction may guarantee
// that a parent is well-formed before creating its children, whereas a
// bottom-up construction completes creation of children before the enveloping
// parent.
template <typename T>
class VectorTree {
  using this_type = VectorTree<T>;

  // Forward declaration
  class ChildrenList;

 public:
  // Self-recursive type that represents children in an expanded view.
  using subnodes_type = std::vector<this_type>;
  using value_type = T;

  VectorTree() : children_(*this) {}

  // Deep copy-constructor.
  VectorTree(const this_type& other)
      : node_value_(other.node_value_),
        parent_(other.parent_),
        children_(*this, other.children_) {}

  VectorTree(this_type&& other) noexcept
      : node_value_(std::move(other.node_value_)),
        parent_(other.parent_),
        children_(*this, std::move(other.children_)) {}

  // This constructor can be used to recursively build trees.
  // e.g.
  //   // looks like function-call, but just invokes constructor:
  //   typedef VectorTree<Foo> FooNode;
  //   auto foo_tree = FooNode({value-initializer},
  //        FooNode({value-initializer}, /* children nodes... */ ),
  //        FooNode({value-initializer}, /* children nodes... */ )
  //   );
  template <typename... Args>
  explicit VectorTree(const value_type& v, Args&&... args)
      : node_value_(v), children_(*this) {
    children_.reserve(sizeof...(args));
    (children_.emplace_back(std::forward<Args>(args)), ...);
  }

  template <typename... Args>
  explicit VectorTree(value_type&& v, Args&&... args)
      : node_value_(std::move(v)), children_(*this) {
    children_.reserve(sizeof...(args));
    (children_.emplace_back(std::forward<Args>(args)), ...);
  }

  ~VectorTree() { CHECK(CheckIntegrity()); }

  // Swaps values and subtrees of two nodes.
  // This operation is safe for unrelated trees (no common ancestor).
  // This operation is safe when the two nodes share a common ancestor,
  // excluding the case where one node is a direct ancestor of the other.
  // TODO(fangism): Add a proper check for this property, and test.
  void swap(this_type& other) noexcept {
    std::swap(node_value_, other.node_value_);
    children_.swap(other.children_);  // efficient O(1) vector::swap
                                      // + O(|children|) linking to parent
  }

  // Copy value and children, but relink new children to this node.
  VectorTree& operator=(const this_type& source) {
    if (this == &source) return *this;
    node_value_ = source.node_value_;
    children_ = source.children_;
    return *this;
  }

  // Explicit move-assignability needed for vector::erase()
  // No need to change parent links when children keep same parent.
  VectorTree& operator=(this_type&& source) noexcept {
    node_value_ = std::move(source.node_value_);
    children_ = std::move(source.children_);
    return *this;
  }

  // Accessors

  T& Value() { return node_value_; }

  const T& Value() const { return node_value_; }

  this_type* Parent() { return parent_; }

  const this_type* Parent() const { return parent_; }

  ChildrenList& Children() { return children_; }

  const ChildrenList& Children() const { return children_; }

 private:
  // Returns true if parent-child links are valid in entire tree.
  bool CheckIntegrity() const {
    for (const auto& child : children_) {
      CHECK_EQ(child.Parent(), this)
          << "Inconsistency: child's parent does not point back to this node!";
      if (!child.CheckIntegrity()) return false;
    }
    return true;
  }

  // A wrapper of a sequence container for storing VectorTree nodes that sets
  // correct parent pointer in each inserted node. The reference to the
  // "correct" parent is passed to a constructor.
  //
  // The sole purpose of this class is to function as a children list in
  // VectorTree, both as a storage and as a public interface for tree
  // manipulation (through reference).
  //
  // This class handles parent pointer assignment for all cases where the
  // children list itself is modified. However, it does not clear or otherwise
  // change parent pointer in removed nodes.
  class ChildrenList : ContainerProxyBase<ChildrenList, subnodes_type> {
    using Base = ContainerProxyBase<ChildrenList, subnodes_type>;
    friend Base;

   public:
    using typename Base::container_type;

    // Import (via `using`) ContainerProxy members supported by std::vector.
    USING_CONTAINER_PROXY_STD_VECTOR_MEMBERS(Base)

    // Move-cast to wrapped container's type. Moves out the container.
    explicit operator container_type() && { return std::move(container_); }

   protected:
    // ContainerProxy interface

    container_type& underlying_container() { return container_; }
    const container_type& underlying_container() const { return container_; }

    void ElementsInserted(iterator first, iterator last) {
      LinkChildrenToParent(iterator_range(first, last));
    }

    // Unused:
    // void ElementsBeingRemoved(iterator first, iterator last)

    // Unused:
    // void ElementsBeingReplaced()

    void ElementsWereReplaced() { LinkChildrenToParent(container_); }

   private:
    // Sets parent pointer of nodes from `children` range to address of `node_`.
    template <class Range>
    void LinkChildrenToParent(Range&& children) {
      for (auto& child : children) {
        child.parent_ = &node_;
      }
    }

    // Allow construction, assignment and direct access to `container_` inside
    // VectorTree.
    friend VectorTree;

    // Hide constructors and assignments from the world. This object is created
    // and assigned-to only in VectorTree.

    explicit ChildrenList(VectorTree& node) : node_(node) {}

    ChildrenList(VectorTree& node, const ChildrenList& other)
        : node_(node), container_(other.container_) {
      LinkChildrenToParent(container_);
    }

    ChildrenList& operator=(const ChildrenList& other) {
      container_ = other.container_;
      LinkChildrenToParent(container_);
      return *this;
    }

    ChildrenList(VectorTree& node, ChildrenList&& other) noexcept
        : node_(node), container_(std::move(other.container_)) {
      // Note: `other` is not notified about the change because it ends up in
      // undefined state as a result of the move.
      LinkChildrenToParent(container_);
    }

    ChildrenList& operator=(ChildrenList&& other) noexcept {
      // Note: `other` is not notified about the change because it ends up in
      // undefined state as a result of the move.
      container_ = std::move(other.container_);
      LinkChildrenToParent(container_);
      return *this;
    }

    // Reference to a VectorTree node in which this object represents a list of
    // children.
    // TODO(mglb): try to get rid of this reference. See:
    // https://github.com/chipsalliance/verible/pull/1252#discussion_r825196108
    // Also look at MapTree::KeyValuePair() - `offsetof` is already used there
    // so it could be user here too.
    VectorTree& node_;

    // Actual data container where the nodes are stored.
    subnodes_type container_;

   public:  // deleted members need to be public.
    // Construction requires parent node reference.
    ChildrenList(const ChildrenList&) = delete;

    // Construction requires parent node reference.
    ChildrenList(ChildrenList&&) = delete;
  };

  // Singular value stored at this node.
  value_type node_value_;

  // Pointer up to parent node.
  // Only the root node of a tree has a nullptr parent_.
  // This value is managed by ChildrenList, constructors, and
  // operator=(). There should be no need to set it manually in other places.
  this_type* parent_ = nullptr;

  // Array of nodes/subtrees.
  ChildrenList children_;
};

// Provide ADL-enabled overload for use by swap implementations.
template <class T>
void swap(VectorTree<T>& left, VectorTree<T>& right) noexcept {
  left.swap(right);
}

}  // namespace verible

#endif  // VERIBLE_COMMON_UTIL_VECTOR_TREE_H_
