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

#include <mcld/ADT/BinTree.h>
#include <mcld/ADT/TypeTraits.h>
#include <mcld/MC/MCLDInput.h>
#include <mcld/Support/Path.h>

#include <string>


namespace mcld {

/** \class template<typename Traits, typename Iterator> PolicyIterator<mcld::Input>
 *  \brief PolicyIterator<mcld::Input> is a partially specific PolicyIterator
 */
template<typename Traits, typename IteratorType>
class PolicyIterator<mcld::Input, Traits, IteratorType> : public PolicyIteratorBase<Input, Traits, IteratorType>
{
public:
  typedef PolicyIterator<Input, Traits, IteratorType> Self;
  typedef PolicyIteratorBase<Input, Traits, IteratorType> Base;
  typedef PolicyIterator<Input, typename Traits::nonconst_traits, IteratorType> iterator;
  typedef PolicyIterator<Input, 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() {}

  bool isGroup() const
  { return !Base::hasData() && !Base::isRoot(); }

  Self& operator++() {
    IteratorType::advance();
    // skip the Group node
    while (isGroup())
      IteratorType::advance();
    return *this;
  }

  Self operator++(int) {
    Self tmp(*this);
    IteratorType::advance();
    // skip the Group node
    while (isGroup())
      IteratorType::advance();
    return tmp;
  }
};

template<>
class BinaryTree<Input> : public BinaryTreeBase<Input>
{
public:
  typedef size_t             size_type;
  typedef ptrdiff_t          difference_type;
  typedef Input              value_type;
  typedef value_type*        pointer;
  typedef value_type&        reference;
  typedef const value_type*  const_pointer;
  typedef const value_type&  const_reference;

  typedef BinaryTree<Input>  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<Input>()
  { }

  ~BinaryTree() {
  }

  // -----  iterators  ----- //
  bfs_iterator bfs_begin()
  {
     bfs_iterator it = bfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
     if (it.isGroup())
       ++it;
     return it;
  }

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

  const_bfs_iterator bfs_begin() const
  {
     const_bfs_iterator it =
                    const_bfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
     if (it.isGroup())
       ++it;
     return it;
  }

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

  dfs_iterator dfs_begin()
  {
    dfs_iterator it = dfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
    if (it.isGroup())
      ++it;
    return it;
  }

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

  const_dfs_iterator dfs_begin() const
  {
    const_dfs_iterator it =
                    const_dfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
    if (it.isGroup())
      ++it;
    return it;
  }

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

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

  const_iterator root() const
  {
    // FIXME: provide the iterater constructors for constant NodeBase instead of
    // using const_cast
    return const_iterator(
                    const_cast<NodeBase*>(&BinaryTreeBase<Input>::m_Root.node));
  }

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

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

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

  const_iterator end() const
  { return const_iterator(BinaryTreeBase<Input>::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 Input& value) {
    node_type *node = BinaryTreeBase<Input>::createNode();
    node->data = const_cast<Input*>(&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<Input>::m_Root.summon(
                                   pTree.BinaryTreeBase<Input>::m_Root);
      BinaryTreeBase<Input>::m_Root.delegate(pTree.m_Root);
      pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
    }
    return *this;
  }
};

/** \class InputTree
 *  \brief InputTree is the input tree to contains all inputs from the
 *  command line.
 *
 *  InputTree, of course, is uncopyable.
 *
 *  @see Input
 */
class InputTree : public BinaryTree<Input>
{
private:
  typedef BinaryTree<Input> BinTreeTy;

public:
  enum Direction {
    Inclusive  = TreeIteratorBase::Leftward,
    Positional = TreeIteratorBase::Rightward
  };

  typedef BinaryTree<Input>::iterator       iterator;
  typedef BinaryTree<Input>::const_iterator const_iterator;

public:
  /** \class Mover
   *  \brief Mover provides the interface for moving iterator forward.
   *
   *  Mover is a function object (functor). @ref Mover::move moves
   *  iterator forward in certain direction. @ref Mover::connect
   *  connects two nodes of the given iterators togather.
   */
  struct Mover {
    virtual ~Mover() {}
    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const = 0;
    virtual void move(TreeIteratorBase& pNode) const = 0;
  };

  /** \class Succeeder
   *  \brief class Succeeder moves the iterator afterward.
   */
  struct Succeeder : public Mover {
    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
      proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
    }

    virtual void move(TreeIteratorBase& pNode) const {
      pNode.move<Positional>();
    }
  };

  /** \class Includer
   *  \brief class Includer moves the iterator downward.
   */
  struct Includer : public Mover {
    virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
      proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
    }

    virtual void move(TreeIteratorBase& pNode) const {
      pNode.move<Inclusive>();
    }
  };

public:
  static Succeeder Afterward;
  static Includer  Downward;

public:

  using BinTreeTy::merge;

  // -----  modify  ----- //
  template<size_t DIRECT>
  InputTree& enterGroup(TreeIteratorBase pRoot);

  template<size_t DIRECT>
  InputTree& insert(TreeIteratorBase pRoot,
                    Input& pInput);

  InputTree& merge(TreeIteratorBase pRoot,
                   const Mover& pMover,
                   InputTree& pTree);

  InputTree& insert(TreeIteratorBase pRoot,
                    const Mover& pMover,
                    Input& pInput);

  InputTree& enterGroup(TreeIteratorBase pRoot,
                        const Mover& pMover);

};

bool isGroup(const InputTree::iterator& pos);
bool isGroup(const InputTree::const_iterator& pos);
bool isGroup(const InputTree::dfs_iterator& pos);
bool isGroup(const InputTree::const_dfs_iterator& pos);
bool isGroup(const InputTree::bfs_iterator& pos);
bool isGroup(const InputTree::const_bfs_iterator& pos);

} // namespace of mcld

//===----------------------------------------------------------------------===//
// template member functions
//===----------------------------------------------------------------------===//
template<size_t DIRECT>
mcld::InputTree&
mcld::InputTree::enterGroup(mcld::TreeIteratorBase pRoot)
{
  BinTreeTy::node_type* node = createNode();
  if (pRoot.isRoot())
    proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
        const_cast<const node_type*>(node));
  else
    proxy::hook<DIRECT>(pRoot.m_pNode,
        const_cast<const node_type*>(node));
  return *this;
}

template<size_t DIRECT>
mcld::InputTree& mcld::InputTree::insert(mcld::TreeIteratorBase pRoot,
	                                 mcld::Input& pInput)
{
  BinTreeTy::node_type* node = createNode();
  node->data = &pInput;
  if (pRoot.isRoot())
    proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
                                         const_cast<const node_type*>(node));
  else
    proxy::hook<DIRECT>(pRoot.m_pNode,
                        const_cast<const node_type*>(node));
  return *this;
}

#endif

