//===- BinTree.h ----------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_BINARY_TREE_H
#define MCLD_BINARY_TREE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif

#include "mcld/ADT/Uncopyable.h"
#include "mcld/ADT/TreeAllocator.h"

#include <cstddef>
#include <iterator>
#include <memory>
#include <queue>
#include <stack>

namespace mcld
{

template<class DataType>
class BinaryTree;

class DFSIterator : public TreeIteratorBase
{
public:
  DFSIterator()
  : TreeIteratorBase()
  { }

  DFSIterator(NodeBase *X)
    : TreeIteratorBase(X) {
    if (hasRightChild())
      m_Stack.push(m_pNode->right);
    if (hasLeftChild())
      m_Stack.push(m_pNode->left);
  }

  virtual ~DFSIterator()
  { }

  void advance() {
    if (m_Stack.empty()) { // reach the end
      m_pNode = m_pNode->right; // should be root
      return;
    }
    m_pNode = m_Stack.top();
    m_Stack.pop();
    if (hasRightChild())
      m_Stack.push(m_pNode->right);
    if (hasLeftChild())
      m_Stack.push(m_pNode->left);
  }

private:
    std::stack<NodeBase *> m_Stack;
};

class BFSIterator : public TreeIteratorBase
{
public:
  BFSIterator()
  : TreeIteratorBase()
  { }

  BFSIterator(NodeBase *X)
    : TreeIteratorBase(X) {
    if (hasRightChild())
      m_Queue.push(m_pNode->right);
    if (hasLeftChild())
      m_Queue.push(m_pNode->left);
  }

  virtual ~BFSIterator()
  { }

  void advance() {
    if (m_Queue.empty()) { // reach the end
      m_pNode = m_pNode->right; // should be root
      return;
    }
    m_pNode = m_Queue.front();
    m_Queue.pop();
    if (hasRightChild())
      m_Queue.push(m_pNode->right);
    if (hasLeftChild())
      m_Queue.push(m_pNode->left);
  }

private:
    std::queue<NodeBase *> m_Queue;
};

template<class DataType, class Traits, class IteratorType>
class PolicyIteratorBase : public IteratorType
{
public:
  typedef DataType                       value_type;
  typedef Traits                         traits;
  typedef typename traits::pointer       pointer;
  typedef typename traits::reference     reference;

  typedef PolicyIteratorBase<value_type, Traits, IteratorType>          Self;
  typedef Node<value_type>                                              node_type;
  typedef typename traits::nonconst_traits                              nonconst_traits;
  typedef PolicyIteratorBase<value_type, nonconst_traits, IteratorType> iterator;
  typedef typename traits::const_traits                                 const_traits;
  typedef PolicyIteratorBase<value_type, const_traits, IteratorType>    const_iterator;
  typedef std::forward_iterator_tag                                     iterator_category;
  typedef size_t                                                        size_type;
  typedef ptrdiff_t                                                     difference_type;

public:
  PolicyIteratorBase()
    : IteratorType() {}

  PolicyIteratorBase(const iterator &X)
    : IteratorType(X.m_pNode) {}

  explicit PolicyIteratorBase(NodeBase* X)
    : IteratorType(X) {}

  virtual ~PolicyIteratorBase() {}

  // -----  operators  ----- //
  pointer operator*() const
  { return static_cast<node_type*>(IteratorType::m_pNode)->data; }

  reference operator->() const
  { return *static_cast<node_type*>(IteratorType::m_pNode)->data; }

  bool isRoot() const
  { return (IteratorType::m_pNode->right == IteratorType::m_pNode); }

  bool hasData() const
  { return (!isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }

};

template<class DataType, class Traits, class IteratorType>
class PolicyIterator : public PolicyIteratorBase<DataType, Traits, IteratorType>
{
public:
  typedef PolicyIterator<DataType, Traits, IteratorType> Self;
  typedef PolicyIteratorBase<DataType, Traits, IteratorType> Base;
  typedef PolicyIterator<DataType, typename Traits::nonconst_traits, IteratorType> iterator;
  typedef PolicyIterator<DataType, typename Traits::const_traits, IteratorType>    const_iterator;

public:
  PolicyIterator()
    : Base() {}

  PolicyIterator(const iterator &X)
    : Base(X.m_pNode) {}

  explicit PolicyIterator(NodeBase* X)
    : Base(X) {}

  virtual ~PolicyIterator() {}

  Self& operator++() {
    IteratorType::advance();
    return *this;
  }

  Self operator++(int) {
    Self tmp = *this;
    IteratorType::advance();
    return tmp;
  }
};

template<class DataType>
class BinaryTree;

/** \class TreeIterator
 *  \brief TreeIterator provides full functions of binary tree's iterator.
 *
 *  TreeIterator is designed to compatible with STL iterators.
 *  TreeIterator is bi-directional. Incremental direction means to move
 *  rightward, and decremental direction is leftward.
 *
 *  @see TreeIteratorBase
 */
template<class DataType, class Traits>
struct TreeIterator : public TreeIteratorBase
{
public:
  typedef DataType                       value_type;
  typedef Traits                         traits;
  typedef typename traits::pointer       pointer;
  typedef typename traits::reference     reference;

  typedef TreeIterator<value_type, Traits>          Self;
  typedef Node<value_type>                          node_type;

  typedef typename traits::nonconst_traits          nonconst_traits;
  typedef TreeIterator<value_type, nonconst_traits> iterator;
  typedef typename traits::const_traits             const_traits;
  typedef TreeIterator<value_type, const_traits>    const_iterator;
  typedef std::bidirectional_iterator_tag           iterator_category;
  typedef size_t                                    size_type;
  typedef ptrdiff_t                                 difference_type;

public:
  TreeIterator()
  : TreeIteratorBase() {}

  TreeIterator(const iterator &X)
    : TreeIteratorBase(X.m_pNode) {}

  ~TreeIterator() {}

  // -----  operators  ----- //
  pointer operator*() const
  { return static_cast<node_type*>(m_pNode)->data; }

  reference operator->() const
  { return *static_cast<node_type*>(m_pNode)->data; }

  bool isRoot() const
  { return (m_pNode->right == m_pNode); }

  bool hasData() const
  { return (!isRoot() && (0 != static_cast<node_type*>(m_pNode)->data)); }

  Self& operator++() {
    this->move<TreeIteratorBase::Rightward>();
    return *this;
  }

  Self operator++(int) {
    Self tmp = *this;
    this->move<TreeIteratorBase::Rightward>();
    return tmp;
  }

  Self& operator--() {
    this->move<TreeIteratorBase::Leftward>();
    return *this;
  }

  Self operator--(int) {
    Self tmp = *this;
    this->move<TreeIteratorBase::Leftward>();
    return tmp;
  }

  explicit TreeIterator(NodeBase* X)
    : TreeIteratorBase(X) {}
};

/** \class BinaryTreeBase
 *  \brief BinaryTreeBase gives root node and memory management.
 *
 *  The memory management of nodes in is hidden by BinaryTreeBase.
 *  BinaryTreeBase also provides the basic functions for merging a tree and
 *  inserton of a node.
 *
 *  @see BinaryTree
 */
template<class DataType>
class BinaryTreeBase : private Uncopyable
{
public:
  typedef Node<DataType> NodeType;
protected:
  /// TreeImpl - TreeImpl records the root node and the number of nodes
  //
  //    +---> Root(end) <---+
  //    |        |left      |
  //    |      begin        |
  //    |     /     \       |
  //    |  Left     Right   |
  //    +---/         \-----+
  //
  class TreeImpl : public NodeFactory<DataType>
  {
    typedef typename NodeFactory<DataType>::iterator       iterator;
    typedef typename NodeFactory<DataType>::const_iterator const_iterator;

  public:
    NodeBase node;

  public:
    TreeImpl()
      : NodeFactory<DataType>() {
      node.left = node.right = &node;
    }

    ~TreeImpl()
    { }

    /// summon - change the final edges of pClient to our root
    void summon(TreeImpl& pClient) {
      if (this == &pClient)
        return;

      iterator data;
      iterator dEnd = pClient.end();
      for (data = pClient.begin(); data!=dEnd; ++data ) {
        if ((*data).left == &pClient.node)
          (*data).left = &node;
        if ((*data).right == &pClient.node)
          (*data).right = &node;
      }
    }
  }; // TreeImpl

protected:
  /// m_Root is a special object who responses:
  //  - the pointer of root
  //  - the simple factory of nodes.
  TreeImpl m_Root;

protected:
  NodeType *createNode() {
    NodeType *result = m_Root.produce();
    result->left = result->right = &m_Root.node;
    return result;
  }

  void destroyNode(NodeType *pNode) {
    pNode->left = pNode->right = 0;
    pNode->data = 0;
    m_Root.deallocate(pNode);
  }

public:
  BinaryTreeBase()
  : m_Root()
  { }

  virtual ~BinaryTreeBase()
  { }

  size_t size() const {
    return m_Root.size();
  }

  bool empty() const {
    return m_Root.empty();
  }

protected:
  void clear() {
    m_Root.clear();
  }
};

/** \class BinaryTree
 *  \brief An abstract data type of binary tree.
 *
 *  @see mcld::InputTree
 */
template<class DataType>
class BinaryTree : public BinaryTreeBase<DataType>
{
public:
  typedef size_t             size_type;
  typedef ptrdiff_t          difference_type;
  typedef DataType           value_type;
  typedef value_type*        pointer;
  typedef value_type&        reference;
  typedef const value_type*  const_pointer;
  typedef const value_type&  const_reference;

  typedef BinaryTree<DataType>  Self;
  typedef TreeIterator<value_type, NonConstTraits<value_type> > iterator;
  typedef TreeIterator<value_type, ConstTraits<value_type> >    const_iterator;

  typedef PolicyIterator<value_type, NonConstTraits<value_type>, DFSIterator> dfs_iterator;
  typedef PolicyIterator<value_type, ConstTraits<value_type>, DFSIterator>    const_dfs_iterator;
  typedef PolicyIterator<value_type, NonConstTraits<value_type>, BFSIterator> bfs_iterator;
  typedef PolicyIterator<value_type, ConstTraits<value_type>, BFSIterator>    const_bfs_iterator;

protected:
  typedef Node<value_type> node_type;

public:
  // -----  constructors and destructor  ----- //
  BinaryTree()
  : BinaryTreeBase<DataType>()
  { }

  ~BinaryTree() {
  }

  // -----  iterators  ----- //
  bfs_iterator bfs_begin()
  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  bfs_iterator bfs_end()
  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  const_bfs_iterator bfs_begin() const
  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  const_bfs_iterator bfs_end() const
  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  dfs_iterator dfs_begin()
  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  dfs_iterator dfs_end()
  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  const_dfs_iterator dfs_begin() const
  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  const_dfs_iterator dfs_end() const
  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  iterator root()
  { return iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }

  const_iterator root() const
  { return const_iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }

  iterator begin()
  { return iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  iterator end()
  { return iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  const_iterator begin() const
  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }

  const_iterator end() const
  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }

  // ----- modifiers  ----- //
  /// join - create a leaf node and merge it in the tree.
  //  This version of join determines the direction on compilation time.
  //  @param DIRECT the direction of the connecting edge of the parent node.
  //  @param position the parent node
  //  @param value the value being pushed.
  template<size_t DIRECT, class Pos>
  BinaryTree& join(Pos position, const DataType& value) {
    node_type *node = BinaryTreeBase<DataType>::createNode();
    node->data = const_cast<DataType*>(&value);
    if (position.isRoot())
      proxy::hook<TreeIteratorBase::Leftward>(position.m_pNode,
                          const_cast<const node_type*>(node));
    else
      proxy::hook<DIRECT>(position.m_pNode,
                          const_cast<const node_type*>(node));
    return *this;
  }

  /// merge - merge the tree
  //  @param DIRECT the direction of the connecting edge of the parent node.
  //  @param position the parent node
  //  @param the tree being joined.
  //  @return the joined tree
  template<size_t DIRECT, class Pos>
  BinaryTree& merge(Pos position, BinaryTree& pTree) {
    if (this == &pTree)
      return *this;

    if (!pTree.empty()) {
      proxy::hook<DIRECT>(position.m_pNode,
                        const_cast<const NodeBase*>(pTree.m_Root.node.left));
      BinaryTreeBase<DataType>::m_Root.summon(
                                   pTree.BinaryTreeBase<DataType>::m_Root);
      BinaryTreeBase<DataType>::m_Root.delegate(pTree.m_Root);
      pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
    }
    return *this;
  }
};

} // namespace of mcld

#endif
