/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#ifndef TRIE_H_
#define TRIE_H_

#include "ns3/ptr.h"

#include <boost/intrusive/unordered_set.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/functional/hash.hpp>
#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
#include <boost/mpl/if.hpp>

namespace ndnSIM
{

/////////////////////////////////////////////////////
// Allow customization for payload
//
template<typename Payload>
struct pointer_payload_traits
{
  typedef Payload         payload_type; // general type of the payload
  typedef Payload*        storage_type; // how the payload is actually stored
  typedef Payload*        insert_type;  // what parameter is inserted

  typedef Payload*        return_type;  // what is returned on access
  typedef const Payload*  const_return_type; // what is returned on const access

  static Payload* empty_payload;
};

template<typename Payload>
Payload*
pointer_payload_traits<Payload>::empty_payload = 0;

template<typename Payload>
struct smart_pointer_payload_traits
{
  typedef Payload                 payload_type;
  typedef ns3::Ptr<Payload>       storage_type;
  typedef ns3::Ptr<Payload>       insert_type;
  
  typedef ns3::Ptr<Payload>       return_type;
  typedef ns3::Ptr<const Payload> const_return_type;
  
  static ns3::Ptr<Payload> empty_payload;
};

template<typename Payload>
ns3::Ptr<Payload>
smart_pointer_payload_traits<Payload>::empty_payload = 0;

template<typename Payload>
struct non_pointer_traits
{
  typedef Payload         payload_type;
  typedef Payload         storage_type;
  typedef const Payload & insert_type; // nothing to insert

  typedef Payload&        return_type;
  typedef const Payload & const_return_type;
  
  static Payload empty_payload;
};

template<typename Payload>
Payload 
non_pointer_traits<Payload>::empty_payload = Payload ();


////////////////////////////////////////////////////
// forward declarations
//
template<typename FullKey,
         typename PayloadTraits,
         typename PolicyHook >
class trie; 

template<typename FullKey, typename PayloadTraits, typename PolicyHook>
inline std::ostream&
operator << (std::ostream &os,
             const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);

template<typename FullKey, typename PayloadTraits, typename PolicyHook>
bool
operator== (const trie<FullKey, PayloadTraits, PolicyHook> &a,
            const trie<FullKey, PayloadTraits, PolicyHook> &b);

template<typename FullKey, typename PayloadTraits, typename PolicyHook >
std::size_t
hash_value (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);

///////////////////////////////////////////////////
// actual definition
//
template<class T>
class trie_iterator;

template<class T>
class trie_point_iterator;

template<typename FullKey,
	 typename PayloadTraits,
         typename PolicyHook >
class trie
{
public:
  typedef typename FullKey::partial_type Key;

  typedef trie*       iterator;
  typedef const trie* const_iterator;

  typedef trie_iterator<trie> recursive_iterator;
  typedef trie_iterator<const trie> const_recursive_iterator;

  typedef trie_point_iterator<trie> point_iterator;
  typedef trie_point_iterator<const trie> const_point_iterator;

  typedef PayloadTraits payload_traits;
  
  inline
  trie (const Key &key, size_t bucketSize = 10, size_t bucketIncrement = 10)
    : key_ (key)
    , initialBucketSize_ (bucketSize)
    , bucketIncrement_ (bucketIncrement)
    , bucketSize_ (initialBucketSize_)
    , buckets_ (new bucket_type [bucketSize_]) //cannot use normal pointer, because lifetime of buckets should be larger than lifetime of the container
    , children_ (bucket_traits (buckets_.get (), bucketSize_))
    , payload_ (PayloadTraits::empty_payload)
    , parent_ (0)
  {
  }

  inline
  ~trie ()
  {
    payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
    children_.clear_and_dispose (trie_delete_disposer ());
  }

  void
  clear ()
  {
    children_.clear_and_dispose (trie_delete_disposer ());
  }

  template<class Predicate>
  void
  clear_if (Predicate cond)
  {
    recursive_iterator trieNode (this);
    recursive_iterator end (0);

    while (trieNode != end)
      {
        if (cond (*trieNode))
          {
            trieNode = recursive_iterator (trieNode->erase ());
          }
        trieNode ++;
      }
  }
  
  // actual entry
  friend bool
  operator== <> (const trie<FullKey, PayloadTraits, PolicyHook> &a,
                 const trie<FullKey, PayloadTraits, PolicyHook> &b);

  friend std::size_t
  hash_value <> (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);

  inline std::pair<iterator, bool>
  insert (const FullKey &key,
          typename PayloadTraits::insert_type payload)
  {
    trie *trieNode = this;
  
    BOOST_FOREACH (const Key &subkey, key)
      {
        typename unordered_set::iterator item = trieNode->children_.find (subkey);
        if (item == trieNode->children_.end ())
          {
            trie *newNode = new trie (subkey, initialBucketSize_, bucketIncrement_);
            // std::cout << "new " << newNode << "\n";
            newNode->parent_ = trieNode;

            if (trieNode->children_.size () >= trieNode->bucketSize_)
              {
                trieNode->bucketSize_ += trieNode->bucketIncrement_;
                buckets_array newBuckets (new bucket_type [trieNode->bucketSize_]);
                trieNode->children_.rehash (bucket_traits (newBuckets.get (), trieNode->bucketSize_));
                trieNode->buckets_.swap (newBuckets);
              }
	  
            std::pair< typename unordered_set::iterator, bool > ret =
              trieNode->children_.insert (*newNode);
	  
            trieNode = &(*ret.first);
          }
        else
          trieNode = &(*item);
      }

    if (trieNode->payload_ == PayloadTraits::empty_payload)
      {
        trieNode->payload_ = payload;
        return std::make_pair (trieNode, true);
      }
    else
      return std::make_pair (trieNode, false);
  }

  /**
   * @brief Removes payload (if it exists) and if there are no children, prunes parents trie
   */
  inline iterator
  erase ()
  {
    payload_ = PayloadTraits::empty_payload;
    return prune ();
  }

  /**
   * @brief Do exactly as erase, but without erasing the payload
   */
  inline iterator
  prune ()
  {
    if (payload_ == PayloadTraits::empty_payload &&
        children_.size () == 0)
      {
        if (parent_ == 0) return this;

        trie *parent = parent_;
        parent->children_.erase_and_dispose (*this, trie_delete_disposer ()); // delete this; basically, committing a suicide

        return parent->prune ();
      }
    return this;
  }

  // inline boost::tuple<const iterator, bool, const iterator>
  // find (const FullKey &key) const
  // {
  //   return const_cast<trie*> (this)->find (key);
  // }

  /**
   * @brief Perform the longest prefix match
   * @param key the key for which to perform the longest prefix match
   *
   * @return ->second is true if prefix in ->first is longer than key
   */
  inline boost::tuple<iterator, bool, iterator>
  find (const FullKey &key)
  {
    trie *trieNode = this;
    iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? this : 0;
    bool reachLast = true;
  
    BOOST_FOREACH (const Key &subkey, key)
      {
        typename unordered_set::iterator item = trieNode->children_.find (subkey);
        if (item == trieNode->children_.end ())
          {
            reachLast = false;
            break;
          }
        else
          {
            trieNode = &(*item);
	  
            if (trieNode->payload_ != PayloadTraits::empty_payload)
              foundNode = trieNode;
          }
      }

    return boost::make_tuple (foundNode, reachLast, trieNode);  
  }

  /**
   * @brief Find next payload of the sub-trie
   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
   */
  inline iterator
  find ()
  {
    if (payload_ != PayloadTraits::empty_payload)
      return this;

    typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
    for (typename trie::unordered_set::iterator subnode = children_.begin ();
         subnode != children_.end ();
         subnode++ )
      // BOOST_FOREACH (trie &subnode, children_)
      {
        iterator value = subnode->find ();
        if (value != 0)
          return value;
      }
  
    return 0;
  }

  /**
   * @brief Find next payload of the sub-trie satisfying the predicate
   * @param pred predicate
   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
   */
  template<class Predicate>
  inline const iterator
  find_if (Predicate pred)
  {
    if (payload_ != PayloadTraits::empty_payload && pred (payload_))
      return this;

    typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
    for (typename trie::unordered_set::iterator subnode = children_.begin ();
         subnode != children_.end ();
         subnode++ )
      // BOOST_FOREACH (const trie &subnode, children_)
      {
        iterator value = subnode->find ();
        if (value != 0)
          return value;
      }
  
    return 0;
  }

  iterator end ()
  {
    return 0;
  }

  const_iterator end () const
  {
    return 0;
  }

  typename PayloadTraits::const_return_type
  payload () const
  {
    return payload_;
  }

  typename PayloadTraits::return_type
  payload ()
  {
    return payload_;
  }

  void
  set_payload (typename PayloadTraits::insert_type payload)
  {
    payload_ = payload;
  }

  Key key () const
  {
    return key_;
  }
  
  inline void
  PrintStat (std::ostream &os) const;  
  
private:
  //The disposer object function
  struct trie_delete_disposer
  {
    void operator() (trie *delete_this)
    {
      delete delete_this;
    }
  };

  template<class D>
  struct array_disposer
  {
    void operator() (D *array)
    {
      delete [] array;
    }
  };

  friend
  std::ostream&
  operator<< < > (std::ostream &os, const trie &trie_node);

public:
  PolicyHook policy_hook_;

private:
  boost::intrusive::unordered_set_member_hook<> unordered_set_member_hook_;

  // necessary typedefs
  typedef trie self_type;
  typedef boost::intrusive::member_hook< trie,
                                         boost::intrusive::unordered_set_member_hook< >,
                                         &trie::unordered_set_member_hook_ > member_hook;

  typedef boost::intrusive::unordered_set< trie, member_hook > unordered_set;
  typedef typename unordered_set::bucket_type   bucket_type;
  typedef typename unordered_set::bucket_traits bucket_traits;

  template<class T>
  friend class trie_iterator;

  template<class T>
  friend class trie_point_iterator;

  ////////////////////////////////////////////////
  // Actual data
  ////////////////////////////////////////////////
  
  Key key_; ///< name component

  size_t initialBucketSize_;
  size_t bucketIncrement_;

  size_t bucketSize_;
  typedef boost::interprocess::unique_ptr< bucket_type, array_disposer<bucket_type> > buckets_array;
  buckets_array buckets_;
  unordered_set children_;
  
  typename PayloadTraits::storage_type payload_;
  trie *parent_; // to make cleaning effective
};




template<typename FullKey, typename PayloadTraits, typename PolicyHook>
inline std::ostream&
operator << (std::ostream &os, const trie<FullKey, PayloadTraits, PolicyHook> &trie_node)
{
  os << "# " << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload)?"*":"") << std::endl;
  typedef trie<FullKey, PayloadTraits, PolicyHook> trie;

  for (typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin ();
       subnode != trie_node.children_.end ();
       subnode++ )
  // BOOST_FOREACH (const trie &subnode, trie_node.children_)
    {
      os << "\"" << &trie_node << "\"" << " [label=\"" << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload)?"*":"") << "\"]\n";
      os << "\"" << &(*subnode) << "\"" << " [label=\"" << subnode->key_ << ((subnode->payload_ != PayloadTraits::empty_payload)?"*":"") << "\"]""\n";
      
      os << "\"" << &trie_node << "\"" << " -> " << "\"" << &(*subnode) << "\"" << "\n";
      os << *subnode;
    }

  return os;
}

template<typename FullKey, typename PayloadTraits, typename PolicyHook>
inline void
trie<FullKey, PayloadTraits, PolicyHook>
::PrintStat (std::ostream &os) const
{
  os << "# " << key_ << ((payload_ != PayloadTraits::empty_payload)?"*":"") << ": " << children_.size() << " children" << std::endl;
  for (size_t bucket = 0, maxbucket = children_.bucket_count ();
       bucket < maxbucket;
       bucket++)
    {
      os << " " << children_.bucket_size (bucket);
    }
  os << "\n";

  typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
  for (typename trie::unordered_set::const_iterator subnode = children_.begin ();
       subnode != children_.end ();
       subnode++ )
  // BOOST_FOREACH (const trie &subnode, children_)
    {
      subnode->PrintStat (os);
    }
}


template<typename FullKey, typename PayloadTraits, typename PolicyHook>
inline bool
operator == (const trie<FullKey, PayloadTraits, PolicyHook> &a,
             const trie<FullKey, PayloadTraits, PolicyHook> &b)
{
  return a.key_ == b.key_;
}

template<typename FullKey, typename PayloadTraits, typename PolicyHook>
inline std::size_t
hash_value (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node)
{
  return boost::hash_value (trie_node.key_);
}



template<class Trie>
class trie_iterator
{
public:
  trie_iterator () : trie_ (0) {}
  trie_iterator (typename Trie::iterator item) : trie_ (item) {}
  trie_iterator (Trie &item) : trie_ (&item) {}
  
  Trie & operator* () { return *trie_; }
  const Trie & operator* () const { return *trie_; }
  Trie * operator-> () { return trie_; }
  const Trie * operator-> () const { return trie_; }
  bool operator== (trie_iterator<const Trie> &other) const { return (trie_ == other.trie_); }
  bool operator== (trie_iterator<Trie> &other) { return (trie_ == other.trie_); }
  bool operator!= (trie_iterator<const Trie> &other) const { return !(*this == other); }
  bool operator!= (trie_iterator<Trie> &other) { return !(*this == other); }
  
  trie_iterator<Trie> &
  operator++ (int)
  {
    if (trie_->children_.size () > 0)
      trie_ = &(*trie_->children_.begin ());
    else
      trie_ = goUp ();
    return *this;
  }

  trie_iterator<Trie> &
  operator++ ()
  {
    (*this)++;
    return *this;
  }  

private:
  typedef typename boost::mpl::if_< boost::is_same<Trie, const Trie>,
                                    typename Trie::unordered_set::const_iterator,
                                    typename Trie::unordered_set::iterator>::type set_iterator;
  
  Trie* goUp ()
  {
    if (trie_->parent_ != 0)
      {
        // typename Trie::unordered_set::iterator item =
        set_iterator item = trie_->parent_->children_.iterator_to (*trie_);
        item++;
        if (item != trie_->parent_->children_.end ())
          {
            return &(*item);
          }
        else
          {
            trie_ = trie_->parent_;
            return goUp ();
          }
      }
    else
      return 0;
  }
private:
  Trie *trie_;
};


template<class Trie>
class trie_point_iterator
{
private:  
  typedef typename boost::mpl::if_< boost::is_same<Trie, const Trie>,
                                    typename Trie::unordered_set::const_iterator,
                                    typename Trie::unordered_set::iterator>::type set_iterator;

public:
  trie_point_iterator () : trie_ (0) {}
  trie_point_iterator (typename Trie::iterator item) : trie_ (item) {}
  trie_point_iterator (Trie &item)
  {
    if (item.children_.size () != 0)
      trie_ = &*item.children_.begin ();
    else
      trie_ = 0;
  }
  
  Trie & operator* () { return *trie_; }
  const Trie & operator* () const { return *trie_; }
  Trie * operator-> () { return trie_; }
  const Trie * operator-> () const { return trie_; }
  bool operator== (trie_point_iterator<const Trie> &other) const { return (trie_ == other.trie_); }
  bool operator== (trie_point_iterator<Trie> &other) { return (trie_ == other.trie_); }
  bool operator!= (trie_point_iterator<const Trie> &other) const { return !(*this == other); }
  bool operator!= (trie_point_iterator<Trie> &other) { return !(*this == other); }
  
  trie_point_iterator<Trie> &
  operator++ (int)
  {
    if (trie_->parent_ != 0)
      {
        set_iterator item = trie_->parent_->children_.iterator_to (*trie_);
        item ++;
        if (item == trie_->parent_->children_.end ())
          trie_ = 0;
        else
          trie_ = &*item;
      }
    else
      {
        trie_ = 0;
      }
    return *this;
  }

  trie_point_iterator<Trie> &
  operator++ ()
  {
    (*this)++;
    return *this;
  }  

private:
  Trie *trie_;
};


} // ndnSIM

#endif // TRIE_H_
