// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

namespace overnet {

template <class T>
class InternalListNode;

template <class T, InternalListNode<T> T::*NodePtr>
class InternalList;

template <class T>
class InternalListNode {
  template <class U, InternalListNode<U> U::*NodePtr>
  friend class InternalList;

 public:
  InternalListNode() = default;
  InternalListNode(const InternalListNode&) = delete;
  InternalListNode& operator=(const InternalListNode&) = delete;
  ~InternalListNode() { assert(owner_ == nullptr); }

 private:
  T* next_ = nullptr;
  T* prev_ = nullptr;
#ifndef NDEBUG
  void* owner_ = nullptr;
#endif
};

template <class T, InternalListNode<T> T::*NodePtr>
class InternalList {
 public:
  InternalList() = default;
  InternalList(const InternalList&) = delete;
  InternalList& operator=(const InternalList&) = delete;
  ~InternalList() {
    while (head_)
      Remove(head_);
  }

  T* Front() { return head_; }
  bool Empty() const { return head_ == nullptr; }

  void PushBack(T* p) {
#ifndef NDEBUG
    assert(Node(p)->owner_ == nullptr);
    Node(p)->owner_ = this;
#endif
    assert(Node(p)->next_ == nullptr);
    assert(Node(p)->prev_ == nullptr);
    if (tail_ == nullptr) {
      assert(head_ == nullptr);
      head_ = tail_ = p;
    } else {
      assert(Node(tail_)->next_ == nullptr);
      Node(p)->prev_ = tail_;
      Node(tail_)->next_ = p;
      tail_ = p;
    }
    size_++;
  }

  void PushFront(T* p) {
#ifndef NDEBUG
    assert(Node(p)->owner_ == nullptr);
    Node(p)->owner_ = this;
#endif
    assert(Node(p)->next_ == nullptr);
    assert(Node(p)->prev_ == nullptr);
    if (head_ == nullptr) {
      assert(tail_ == nullptr);
      head_ = tail_ = p;
    } else {
      assert(Node(head_)->prev_ == nullptr);
      Node(p)->next_ = head_;
      Node(head_)->prev_ = p;
      head_ = p;
    }
    size_++;
  }

  void Remove(T* p) {
#ifndef NDEBUG
    assert(Node(p)->owner_ == this);
    Node(p)->owner_ = nullptr;
#endif
    if (p == head_) {
      head_ = Node(p)->next_;
      if (head_ == nullptr) {
        assert(p == tail_);
        head_ = tail_ = nullptr;
      } else {
        Node(head_)->prev_ = nullptr;
      }
    } else if (p == tail_) {
      tail_ = Node(p)->prev_;
      assert(tail_ != nullptr);  // otherwise p == head_ at start is true
      Node(tail_)->next_ = nullptr;
    } else {
      Node(Node(p)->next_)->prev_ = Node(p)->prev_;
      Node(Node(p)->prev_)->next_ = Node(p)->next_;
    }
    Node(p)->next_ = Node(p)->prev_ = nullptr;
    size_--;
  }

  T* PopFront() {
    T* p = Front();
    if (p)
      Remove(p);
    return p;
  }

  class Iterator {
   public:
    Iterator(T* node) : p_(node) {}
    bool operator!=(Iterator other) const { return p_ != other.p_; }
    Iterator& operator++() {
      p_ = Node(p_)->next_;
      return *this;
    }
    T* operator*() { return p_; }

   private:
    T* p_;
  };

  Iterator begin() { return Iterator(head_); }
  Iterator end() { return Iterator(nullptr); }

  size_t Size() const { return size_; }

 private:
  static InternalListNode<T>* Node(T* p) { return &(p->*NodePtr); }

  T* head_ = nullptr;
  T* tail_ = nullptr;
  size_t size_ = 0;
};

}  // namespace overnet