/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2011-2015  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * ndnSIM 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
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#ifndef MULTI_POLICY_CONTAINER_H_
#define MULTI_POLICY_CONTAINER_H_

#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/at.hpp>

namespace ns3 {
namespace ndn {
namespace ndnSIM {
namespace detail {

template<class Base, class Value>
struct policy_wrap {
  policy_wrap(Base& base)
    : value_(base)
  {
  }
  Value value_;
};

template<class Base, class Super /*empy_wrap/previous level*/,
         class Value /*policy_wrap< element in vector >*/>
struct inherit_with_base : Super, Value {
  inherit_with_base(Base& base)
    : Super(base)
    , Value(base)
  {
  }

  void
  update(typename Base::iterator item)
  {
    Value::value_.update(item);
    Super::update(item);
  }

  bool
  insert(typename Base::iterator item)
  {
    bool ok = Value::value_.insert(item);
    if (!ok)
      return false;

    ok = Super::insert(item);
    if (!ok) {
      Value::value_.erase(item);
      return false;
    }
    return true;
  }

  void
  lookup(typename Base::iterator item)
  {
    Value::value_.lookup(item);
    Super::lookup(item);
  }

  void
  erase(typename Base::iterator item)
  {
    Value::value_.erase(item);
    Super::erase(item);
  }

  void
  clear()
  {
    Value::value_.clear();
    Super::clear();
  }
};

template<class Base>
struct empty_policy_wrap {
  empty_policy_wrap(Base& base)
  {
  }

  void
  update(typename Base::iterator item)
  {
  }
  bool
  insert(typename Base::iterator item)
  {
    return true;
  }
  void
  lookup(typename Base::iterator item)
  {
  }
  void
  erase(typename Base::iterator item)
  {
  }
  void
  clear()
  {
  }
};

template<class Base, class Vector>
struct multi_policy_container
  : public boost::mpl::
      fold<Vector, empty_policy_wrap<Base>,
           inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                             policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
  typedef typename boost::mpl::
    fold<Vector, empty_policy_wrap<Base>,
         inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                           policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;

  typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
  typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;

  iterator
  begin()
  {
    return this->get<0>().begin();
  }
  const_iterator
  begin() const
  {
    return this->get<0>().begin();
  }

  iterator
  end()
  {
    return this->get<0>().end();
  }
  const_iterator
  end() const
  {
    return this->get<0>().end();
  }

  size_t
  size() const
  {
    return this->get<0>().size();
  }

  multi_policy_container(Base& base)
    : super(base)
  {
  }

  template<int N>
  struct index {
    typedef typename boost::mpl::at_c<Vector, N>::type type;
  };

  template<class T>
  T&
  get()
  {
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<class T>
  const T&
  get() const
  {
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  typename boost::mpl::at_c<Vector, N>::type&
  get()
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  const typename boost::mpl::at_c<Vector, N>::type&
  get() const
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }
};

} // detail
} // ndnSIM
} // ndn
} // ns3

#endif // MULTI_POLICY_CONTAINER_H_
