/*
 * Copyright © 2019 Google, LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "inflight_list.h"
#include <time.h>

static uint64_t gettime_ns(void)
{
   struct timespec current;
   clock_gettime(CLOCK_MONOTONIC, &current);
   constexpr uint64_t kNsecPerSec =  1000000000;
   return static_cast<uint64_t>(current.tv_sec * kNsecPerSec + current.tv_nsec);
}

static uint64_t get_relative_timeout(uint64_t abs_timeout)
{
   uint64_t now = gettime_ns();

   if (abs_timeout < now)
      return 0;
   return abs_timeout - now;
}

static magma_status_t wait_notification_channel(magma_handle_t channel, int64_t timeout_ns)
{
   magma_poll_item_t item = {
       .handle = channel,
       .type = MAGMA_POLL_TYPE_HANDLE,
       .condition = MAGMA_POLL_CONDITION_READABLE,
   };
   return magma_poll(&item, 1, timeout_ns);
}

InflightList::InflightList()
{
   wait_ = wait_notification_channel;
   read_ = magma_connection_read_notification_channel;
}

InflightList::~InflightList()
{
}

void InflightList::add( uint64_t buffer_id)
{
   assert(buffer_id != 0);
   buffers_.push_back(buffer_id);
}

bool InflightList::remove(uint64_t buffer_id)
{
   auto it = std::find(buffers_.begin(), buffers_.end(), buffer_id);
   if (it == buffers_.end()) {
      return false;
   }
   buffers_.erase(it);
   return true;
}

bool InflightList::is_inflight(uint64_t buffer_id)
{
   return std::find(buffers_.begin(), buffers_.end(), buffer_id) != buffers_.end();
}

bool InflightList::TryUpdate(magma_connection_t connection)
{
   if (!mutex_.try_lock()) {
      return false;
   }

   update(connection);

   mutex_.unlock();

   return true;
}

magma_status_t InflightList::WaitForBuffer(magma_connection_t connection,
                                           magma_handle_t notification_channel, uint64_t buffer_id,
                                           uint64_t timeout_ns)
{
   // Calculate deadline before potentially blocking on the mutex
   uint64_t start = gettime_ns();
   uint64_t deadline = start + timeout_ns;

   std::lock_guard<std::mutex> lock(mutex_);

   magma_status_t status = MAGMA_STATUS_OK;

   if (is_inflight(buffer_id)) {

      while (true) {
         // First pass optimization: optimistically try reading the notification channel;
         // may avoid an unnecessary wait.
         update(connection);

         if (!is_inflight(buffer_id))
            break;

         if (timeout_ns == 0) {
            // Optimization: don't bother making the wait system call since the notification
            // channel was just drained.
            status = MAGMA_STATUS_TIMED_OUT;
            break;
         }

         status = wait_(notification_channel, get_relative_timeout(deadline));
         if (status != MAGMA_STATUS_OK) {
            break;
         }
      }
   }

   return status;
}

void InflightList::AddAndUpdate(magma_connection_t connection,
                               struct magma_exec_resource* resources, uint32_t count)
{
   std::lock_guard<std::mutex> lock(mutex_);

   for (uint32_t i = 0; i < count; i++) {
      add(resources[i].buffer_id);
   }

   update(connection);
}

void InflightList::update(magma_connection_t connection)
{
   uint64_t bytes_available = 0;
   magma_bool_t more_data = false;
   while (true) {
      magma_status_t status =
          read_(connection, notification_buffer, sizeof(notification_buffer),
                      &bytes_available, &more_data);
      if (status != MAGMA_STATUS_OK) {
         return;
      }
      if (bytes_available == 0)
         return;
      assert(bytes_available % sizeof(uint64_t) == 0);
      for (uint32_t i = 0; i < bytes_available / sizeof(uint64_t); i++) {
         assert(is_inflight(notification_buffer[i]));
         remove(notification_buffer[i]);
      }
      if (!more_data)
         return;
   }
}
