/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2017, Regents of the University of California.
 *
 * This file is part of NDN repo-ng (Next generation of NDN repository).
 * See AUTHORS.md for complete list of repo-ng authors and contributors.
 *
 * repo-ng 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.
 *
 * repo-ng 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
 * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP
#define REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP

#include "common.hpp"

#include <random>

namespace update2 {

class SkipList32Levels25Probabilty
{
public:
  static size_t
  getMaxLevels()
  {
    return 32;
  }

  static double
  getProbability()
  {
    return 0.25;  // 25%
  }
};

template<typename T>
struct SkipListNode
{
  typedef SkipListNode<T>* SkipListNodePointer;
  T data;
  std::vector<SkipListNodePointer> prevs;
  std::vector<SkipListNodePointer> nexts;
};

template<typename T, class Ref, class Ptr>
class SkipListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
public:
  typedef SkipListNode<T>* NodePointer;
  NodePointer node;

  typedef SkipListIterator<T, Ref, Ptr> Self;
  typedef T value_type;
  typedef Ptr pointer;
  typedef Ref reference;
  typedef ptrdiff_t difference_type;
  typedef SkipListIterator<T, const T&, const T*> const_iterator;
  /// alias of const_iterator
  typedef const_iterator iterator;

public:
  // constructor
  SkipListIterator()
  {
  }

  explicit
  SkipListIterator(NodePointer x)
    : node(x)
  {
  }

  SkipListIterator(const SkipListIterator& x)
    : node(x.node)
  {
  }

  bool
  operator==(const const_iterator& x) const
  {
    return node == x.node;
  }

  bool
  operator!=(const const_iterator& x) const
  {
    return node != x.node;
  }

  reference
  operator*() const
  {
    return (*node).data;
  }

  pointer
  operator->() const
  {
    return &(operator*());
  }

  Self&
  operator++()
  {
    node = node->nexts.front();
    return *this;
  }

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

  Self&
  operator--()
  {
    node = node->prevs.front();
    return *this;
  }

  Self
  operator--(int)
  {
    Self tmp = *this;
    --*this;
    return tmp;
  }
};

/*
 * @brief SkipList
 *
 * Examples of internal structure:
 * "A <-i-> B" means A->nexts[i] = B and B->prevs[i] = A
 *
 * case 1: an empty skip list
 * m_head <-0-> m_head
 *
 * case 2: a skip list with only one level and only one node
 * m_head <-0-> A <-0-> m_head
 *
 * case 3: a skip list with three nodes, node A and B appear on one level,
 * node C appears on two levels
 * m_head         <-1->         C <-1-> m_head
 * m_head <-0-> A <-0-> B <-0-> C <-0-> m_head
 */

template<typename T, typename Compare = std::less<T>,
         typename Traits = SkipList32Levels25Probabilty>
class SkipList
{
public:
  typedef T value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef value_type& reference;
  typedef const value_type& const_reference;
  typedef SkipListNode<T> Node;
  typedef Node* NodePointer;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef SkipListIterator<T, const T&, const T*> const_iterator;
  /// alias of const_iterator
  typedef const_iterator iterator;
  typedef SkipListNode<T>* SkipListNodePointer;

public:
  explicit
  SkipList()
  {
    initializeHead();
  }

  ~SkipList()
  {
    clear();
    delete(m_head);
  }

  const_iterator
  begin() const
  {
    return const_iterator(*(*m_head).nexts.begin());
  }

  const_iterator
  end() const
  {
    return const_iterator(m_head);
  }

  bool
  empty() const
  {
    return *(m_head->nexts.begin()) == m_head;
  }

  size_t
  size() const
  {
    return m_size;
  }

  const_iterator
  lower_bound(const T& x) const;

  const_iterator
  find(const T& x) const;

  std::pair<const_iterator, bool>
  insert(const T& x);

  const_iterator
  erase(const_iterator it);

protected:

  /*
   * @brief initialize the node
   */
  NodePointer
  createNode()
  {
    NodePointer p = new Node;
    return p;
  }

  /*
   * @brief initialize the node with given value
   * @para to be set to the value of node
   */
  NodePointer
  createNode(const T& x)
  {
    NodePointer p = new Node;
    m_dataAllocator.construct(&(p->data), x);
    return p;
  }

  /*
   * @brief destructror of the node
   * @para given pointer of node to be destructed
   */
  void
  destroyNode(NodePointer p)
  {
    delete(p);
  }

  /*
   * @brief initialize the head
   */
  void
  initializeHead()
  {
    m_head = createNode();
    m_head->prevs.push_back(m_head);
    m_head->nexts.push_back(m_head);
    m_size = 0;
  }

  /*
   * @brief destroy all the nodes of skiplist except the head
   */
  void
  clear()
  {
    NodePointer cur = m_head->nexts[0];
    while (cur != m_head) {
      NodePointer tmp = cur;
      cur = cur->nexts[0];
      destroyNode(tmp);
    }
    m_head->nexts[0] = m_head;
    m_head->prevs[0] = m_head;
  }

  /*
   * @brief pick a random height for inserted skiplist entry
   */
  size_t
  pickRandomLevel() const
  {
    static std::mt19937 gen(std::random_device{}());
    static std::geometric_distribution<size_t> dist(Traits::getProbability());
    return std::min(dist(gen), Traits::getMaxLevels());
  }

protected:
  NodePointer m_head;
  std::allocator<T> m_dataAllocator;
  Compare m_compare;
  size_t m_size;
};


template<typename T, typename Compare, typename Traits>
typename SkipList<T, Compare, Traits>::const_iterator
SkipList<T, Compare, Traits>::lower_bound(const T& x) const
{
  size_t nLevels = m_head->nexts.size();
  NodePointer p = m_head;
  NodePointer q = p->nexts[nLevels - 1];
  for (int i = nLevels - 1; i >= 0; --i) {
    q = p->nexts[i];
    if (q != m_head) {
      while (m_compare(q->data, x)) {
        p = p->nexts[i];
        q = p->nexts[i];
        if (q == m_head) {
          break;
        }
      }
    }
  }
  return const_iterator(q);
}

template<typename T, typename Compare, typename Traits>
typename SkipList<T, Compare, Traits>::const_iterator
SkipList<T, Compare, Traits>::find(const T& x) const
{
  const_iterator it = this->lower_bound(x);
  if (it == this->end() || *it != x)
    return this->end();
  return it;
}

template<typename T, typename Compare, typename Traits>
std::pair<typename SkipList<T, Compare, Traits>::const_iterator, bool>
SkipList<T, Compare, Traits>::insert(const T& x)
{
  size_t nLevels = m_head->nexts.size();
  // 1. find insert position
  std::vector<NodePointer> insertPositions(nLevels);
  NodePointer p = m_head;
  NodePointer q = p->nexts[nLevels - 1];
  for (int i = nLevels - 1; i >= 0; --i) {
    q = p->nexts[i];
    if (q != m_head) {
      while (m_compare(q->data, x)) {
        p = p->nexts[i];
        q = p->nexts[i];
        if (q == m_head) {
          break;
        }
      }
    }
    insertPositions[i] = p;
  }
  // 2. whether q->data == x?
  if (q != m_head)
    if (!m_compare(q->data, x) && !m_compare(x, q->data)) {
      return std::pair<const_iterator, bool>(const_iterator(q), false);
    }
  // 3. construct new node;
  NodePointer newNode = createNode(x);
  // 4. pick random nLevels
  size_t newLevel = pickRandomLevel();
  // 5. insert the new node
  newNode->nexts.resize(newLevel + 1);
  newNode->prevs.resize(newLevel + 1);
  if (newLevel > nLevels - 1) {
    m_head->nexts.resize(newLevel + 1, m_head);
    m_head->prevs.resize(newLevel + 1, m_head);
    insertPositions.resize(newLevel + 1, m_head);
  }
  for (size_t i = 0; i <= newLevel; i++) {
    newNode->nexts[i] = insertPositions[i]->nexts[i];
    newNode->prevs[i] = insertPositions[i];
    insertPositions[i]->nexts[i] = newNode;
    newNode->nexts[i]->prevs[i] = newNode;
  }

  ++m_size;
  return std::pair<const_iterator, bool>(const_iterator(newNode), true);
}

template<typename T, typename Compare, typename Traits>
typename SkipList<T, Compare, Traits>::const_iterator
SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::const_iterator it)
{
  NodePointer eraseNode = it.node;
  if (!empty() && eraseNode != m_head) {
    NodePointer returnNode = eraseNode->nexts[0];
    size_t nLevels = eraseNode->nexts.size();
    for (int i = nLevels - 1; i >= 0; --i) {
      eraseNode->nexts[i]->prevs[i] = eraseNode->prevs[i];
      eraseNode->prevs[i]->nexts[i] = eraseNode->nexts[i];
      // clear empty nLevels
      if ((eraseNode->nexts[i] == eraseNode->prevs[i]) && i > 0) {
        m_head->nexts.pop_back();
        m_head->prevs.pop_back();
      }
    }
    destroyNode(eraseNode);
    --m_size;
    return const_iterator(returnNode);
  }
  else {
    return end();
  }

}

} // namespace update2

#endif // REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP
