#pragma once

#ifndef GEODE_QUEUE_H_
#define GEODE_QUEUE_H_

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <deque>

#include <ace/Condition_Recursive_Thread_Mutex.h>
#include <ace/Guard_T.h>
#include <ace/Recursive_Thread_Mutex.h>
#include <ace/Time_Value.h>

namespace apache {
namespace geode {
namespace client {

template <class T>
class APACHE_GEODE_EXPORT Queue {
 public:
  /**
   * Constructor with parameter to specify whether the contained objects
   * should be deleted in the destructor, and maximum size of queue.
   */
  explicit Queue(bool deleteObjs = true, const uint32_t maxSize = 0)
      : m_cond(m_mutex),
        m_deleteObjs(deleteObjs),
        m_maxSize(maxSize),
        m_closed(false) {}

  ~Queue() { close(); }

  T get() {
    ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
    return getNoLock();
  }

  /** wait "sec" secs, "usec" micros time until notified */
  T getUntil(uint32_t sec, uint32_t usec = 0) {
    auto&& mp = get();

    if (mp == nullptr) {
      ACE_Time_Value interval(sec + usec / 1000000, usec % 1000000);
      ACE_Time_Value stopAt(ACE_OS::gettimeofday());
      stopAt += interval;

      while (!m_closed && mp == nullptr && ACE_OS::gettimeofday() < stopAt) {
        ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
        if (m_cond.wait(&stopAt) != -1) mp = getNoLock();
      }
    }
    return mp;
  }

  bool put(T mp) {
    ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
    if (m_maxSize > 0 && m_queue.size() >= m_maxSize) {
      return false;
    }
    return putNoLock(mp);
  }

  bool putUntil(T mp, uint32_t sec, uint32_t usec = 0) {
    if (m_maxSize > 0) {
      {
        ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
        if (m_queue.size() < m_maxSize) {
          return putNoLock(mp);
        }
      }
      ACE_Time_Value interval(sec + usec / 1000000, usec % 1000000);
      ACE_Time_Value stopAt(ACE_OS::gettimeofday());
      stopAt += interval;

      while (ACE_OS::gettimeofday() < stopAt) {
        ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
        m_cond.wait(&stopAt);
        if (m_queue.size() < m_maxSize) {
          return putNoLock(mp);
        }
      }
      return false;
    } else {
      ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
      return putNoLock(mp);
    }
  }

  void open() {
    ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
    m_closed = false;
  }

  void close() {
    ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);

    if (m_deleteObjs) {
      while (m_queue.size() > 0) {
        auto&& mp = m_queue.back();
        m_queue.pop_back();
      }
    } else {
      m_queue.clear();
    }
    m_closed = true;
    m_cond.signal();
  }

  uint32_t size() {
    ACE_Guard<ACE_Recursive_Thread_Mutex> _guard(m_mutex);
    return static_cast<uint32_t>(m_queue.size());
  }

  bool empty() { return (size() == 0); }

 private:
  inline T getNoLock() {
    T mp = nullptr;

    uint32_t queueSize = static_cast<uint32_t>(m_queue.size());
    if (queueSize > 0) {
      mp = m_queue.back();
      m_queue.pop_back();
      // signal the waiting putter threads, if any
      if (m_maxSize > 0 && queueSize == m_maxSize) {
        m_cond.signal();
      }
    }
    return mp;
  }

  inline bool putNoLock(T mp) {
    if (!m_closed) {
      m_queue.push_front(mp);
      // signal the waiting getter threads, if any
      if (m_queue.size() == 1) {
        m_cond.signal();
      }
      return true;
    }
    return false;
  }

  std::deque<T> m_queue;
  ACE_Recursive_Thread_Mutex m_mutex;
  ACE_Condition<ACE_Recursive_Thread_Mutex> m_cond;
  bool m_deleteObjs;
  const uint32_t m_maxSize;
  bool m_closed;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_QUEUE_H_
