#include "include/dvr/dvr_api.h"
#include "include/dvr/dvr_buffer_queue.h"

#include <android/native_window.h>
#include <private/dvr/buffer_hub_queue_producer.h>

#include "dvr_internal.h"
#include "dvr_buffer_queue_internal.h"

using namespace android;
using android::dvr::BufferConsumer;
using android::dvr::BufferHubBuffer;
using android::dvr::BufferHubQueueProducer;
using android::dvr::BufferProducer;
using android::dvr::ConsumerQueue;
using android::dvr::ProducerQueue;
using android::dvr::ProducerQueueConfigBuilder;
using android::dvr::UsagePolicy;

extern "C" {

DvrWriteBufferQueue::DvrWriteBufferQueue(
    const std::shared_ptr<ProducerQueue>& producer_queue)
    : producer_queue_(producer_queue),
      width_(producer_queue->default_width()),
      height_(producer_queue->default_height()),
      format_(producer_queue->default_format()) {}

int DvrWriteBufferQueue::GetNativeWindow(ANativeWindow** out_window) {
  if (native_window_ == nullptr) {
    // Lazy creation of |native_window|, as not everyone is using
    // DvrWriteBufferQueue as an external surface.
    sp<IGraphicBufferProducer> gbp =
        BufferHubQueueProducer::Create(producer_queue_);
    native_window_ = new Surface(gbp, true);
  }

  *out_window = static_cast<ANativeWindow*>(native_window_.get());
  return 0;
}

int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
  std::unique_ptr<ConsumerQueue> consumer_queue =
      producer_queue_->CreateConsumerQueue();
  if (consumer_queue == nullptr) {
    ALOGE(
        "DvrWriteBufferQueue::CreateReadQueue: Failed to create consumer queue "
        "from producer queue: queue_id=%d.", producer_queue_->id());
    return -ENOMEM;
  }

  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
  return 0;
}

int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer,
                                 int* out_fence_fd) {
  DvrNativeBufferMetadata meta;
  DvrWriteBuffer* buffer = nullptr;
  int fence_fd = -1;
  if (const int ret = GainBuffer(timeout, &buffer, &meta, &fence_fd))
    return ret;
  if (!buffer)
    return -ENOMEM;

  write_buffers_[buffer->slot].reset(buffer);
  write_buffer->write_buffer = std::move(buffer->write_buffer);
  *out_fence_fd = fence_fd;
  return 0;
}

int DvrWriteBufferQueue::GainBuffer(int timeout,
                                    DvrWriteBuffer** out_write_buffer,
                                    DvrNativeBufferMetadata* out_meta,
                                    int* out_fence_fd) {
  size_t slot;
  pdx::LocalHandle release_fence;

  // Need to retry N+1 times, where N is total number of buffers in the queue.
  // As in the worst case, we will dequeue all N buffers and reallocate them, on
  // the {N+1}th dequeue, we are guaranteed to get a buffer with new dimension.
  size_t max_retries = 1 + producer_queue_->capacity();
  size_t retry = 0;

  for (; retry < max_retries; retry++) {
    auto buffer_status =
        producer_queue_->Dequeue(timeout, &slot, out_meta, &release_fence);
    if (!buffer_status) {
      ALOGE_IF(buffer_status.error() != ETIMEDOUT,
               "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer: %s",
               buffer_status.GetErrorMessage().c_str());
      return -buffer_status.error();
    }

    if (write_buffers_[slot] == nullptr) {
      // Lazy initialization of a write_buffers_ slot. Note that a slot will
      // only be dynamically allocated once during the entire cycle life of a
      // queue.
      write_buffers_[slot] = std::make_unique<DvrWriteBuffer>();
      write_buffers_[slot]->slot = slot;
    }

    LOG_ALWAYS_FATAL_IF(
        write_buffers_[slot]->write_buffer,
        "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot);
    write_buffers_[slot]->write_buffer = std::move(buffer_status.take());

    const auto& buffer_producer = write_buffers_[slot]->write_buffer;
    if (!buffer_producer)
      return -ENOMEM;

    if (width_ == buffer_producer->width() &&
        height_ == buffer_producer->height() &&
        format_ == buffer_producer->format()) {
      // Producer queue returns a buffer matches the current request.
      break;
    }

    // Needs reallocation. Note that if there are already multiple available
    // buffers in the queue, the next one returned from |queue_->Dequeue| may
    // still have the old buffer dimension or format. Retry up to N+1 times or
    // until we dequeued a buffer with new configuration.
    ALOGD_IF(TRACE,
             "DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu "
             "(w=%u, h=%u, fmt=%u) is different from the buffer returned "
             "(w=%u, h=%u, fmt=%u). Need re-allocation.",
             slot, width_, height_, format_, buffer_producer->width(),
             buffer_producer->height(), buffer_producer->format());

    // Currently, we are not storing |layer_count| and |usage| in queue
    // configuration. Copy those setup from the last buffer dequeued before we
    // remove it.
    uint32_t old_layer_count = buffer_producer->layer_count();
    uint64_t old_usage = buffer_producer->usage();

    // Allocate a new producer buffer with new buffer configs. Note that if
    // there are already multiple available buffers in the queue, the next one
    // returned from |queue_->Dequeue| may still have the old buffer dimension
    // or format. Retry up to BufferHubQueue::kMaxQueueCapacity times or until
    // we dequeued a buffer with new configuration.
    auto remove_status = producer_queue_->RemoveBuffer(slot);
    if (!remove_status) {
      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to remove buffer: %s",
            remove_status.GetErrorMessage().c_str());
      return -remove_status.error();
    }
    // Make sure that the previously allocated buffer is dereferenced from
    // write_buffers_ array.
    write_buffers_[slot]->write_buffer = nullptr;

    auto allocate_status = producer_queue_->AllocateBuffer(
        width_, height_, old_layer_count, format_, old_usage);
    if (!allocate_status) {
      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to allocate buffer: %s",
            allocate_status.GetErrorMessage().c_str());
      return -allocate_status.error();
    }
  }

  if (retry >= max_retries) {
    ALOGE(
        "DvrWriteBufferQueue::Dequeue: Failed to re-allocate buffer after "
        "resizing.");
    return -ENOMEM;
  }

  *out_write_buffer = write_buffers_[slot].release();
  *out_fence_fd = release_fence.Release();

  return 0;
}

int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer,
                                    const DvrNativeBufferMetadata* meta,
                                    int ready_fence_fd) {
  LOG_FATAL_IF(
      (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()),
      "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);

  // Some basic sanity checks before we put the buffer back into a slot.
  size_t slot = static_cast<size_t>(write_buffer->slot);
  if (write_buffers_[slot] != nullptr) {
    ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot);
    return -EINVAL;
  }
  if (write_buffer->write_buffer == nullptr) {
    ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer.");
    return -EINVAL;
  }
  if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) {
    ALOGE(
        "DvrWriteBufferQueue::PostBuffer: Buffer to be posted does not "
        "belong to this buffer queue. Posting buffer: id=%d, buffer in "
        "queue: id=%d",
        write_buffer->write_buffer->id(), producer_queue_->GetBufferId(slot));
    return -EINVAL;
  }

  write_buffer->write_buffer->SetQueueIndex(next_post_index_++);
  pdx::LocalHandle fence(ready_fence_fd);
  const int ret = write_buffer->write_buffer->PostAsync(meta, fence);
  if (ret < 0) {
    ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d",
          ret);
    return ret;
  }

  // Put the DvrWriteBuffer pointer back into its slot for reuse.
  write_buffers_[slot].reset(write_buffer);
  // It's import to reset the write buffer client now. It should stay invalid
  // until next GainBuffer on the same slot.
  write_buffers_[slot]->write_buffer = nullptr;
  return 0;
}

int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) {
  if (width == 0 || height == 0) {
    ALOGE(
        "DvrWriteBufferQueue::ResizeBuffer: invalid buffer dimension: w=%u, "
        "h=%u.",
        width, height);
    return -EINVAL;
  }

  width_ = width;
  height_ = height;
  return 0;
}

int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format,
                              uint32_t layer_count, uint64_t usage,
                              size_t capacity, size_t metadata_size,
                              DvrWriteBufferQueue** out_write_queue) {
  if (!out_write_queue)
    return -EINVAL;

  auto config_builder = ProducerQueueConfigBuilder()
                            .SetDefaultWidth(width)
                            .SetDefaultHeight(height)
                            .SetDefaultFormat(format)
                            .SetMetadataSize(metadata_size);
  std::unique_ptr<ProducerQueue> producer_queue =
      ProducerQueue::Create(config_builder.Build(), UsagePolicy{});
  if (!producer_queue) {
    ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue.");
    return -ENOMEM;
  }

  auto status = producer_queue->AllocateBuffers(width, height, layer_count,
                                                format, usage, capacity);
  if (!status.ok()) {
    ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers.");
    return -ENOMEM;
  }

  *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue));
  return 0;
}

void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
  delete write_queue;
}

ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
  if (!write_queue)
    return -EINVAL;

  return write_queue->capacity();
}

int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) {
  if (!write_queue)
    return -EINVAL;

  return write_queue->id();
}

int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
                                          ANativeWindow** out_window) {
  ALOGW(
      "dvrWriteBufferQueueGetExternalSurface: This API has been deprecated and "
      "renamed to dvrWriteBufferQueueGetANativeWindow.");
  return dvrWriteBufferQueueGetANativeWindow(write_queue, out_window);
}

int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
                                        ANativeWindow** out_window) {
  if (!write_queue || !out_window)
    return -EINVAL;

  return write_queue->GetNativeWindow(out_window);
}

int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
                                       DvrReadBufferQueue** out_read_queue) {
  if (!write_queue || !out_read_queue)
    return -EINVAL;

  return write_queue->CreateReadQueue(out_read_queue);
}

int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
                               DvrWriteBuffer* write_buffer,
                               int* out_fence_fd) {
  if (!write_queue || !write_buffer || !out_fence_fd)
    return -EINVAL;

  return write_queue->Dequeue(timeout, write_buffer, out_fence_fd);
}

int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
                                  DvrWriteBuffer** out_write_buffer,
                                  DvrNativeBufferMetadata* out_meta,
                                  int* out_fence_fd) {
  if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd)
    return -EINVAL;

  return write_queue->GainBuffer(timeout, out_write_buffer, out_meta,
                                 out_fence_fd);
}

int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
                                  DvrWriteBuffer* write_buffer,
                                  const DvrNativeBufferMetadata* meta,
                                  int ready_fence_fd) {
  if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta)
    return -EINVAL;

  return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd);
}

int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
                                    uint32_t width, uint32_t height) {
  if (!write_queue)
    return -EINVAL;

  return write_queue->ResizeBuffer(width, height);
}

// ReadBufferQueue

DvrReadBufferQueue::DvrReadBufferQueue(
    const std::shared_ptr<ConsumerQueue>& consumer_queue)
    : consumer_queue_(consumer_queue) {}

int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
  std::unique_ptr<ConsumerQueue> consumer_queue =
      consumer_queue_->CreateConsumerQueue();
  if (consumer_queue == nullptr) {
    ALOGE(
        "DvrReadBufferQueue::CreateReadQueue: Failed to create consumer queue "
        "from producer queue: queue_id=%d.", consumer_queue_->id());
    return -ENOMEM;
  }

  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
  return 0;
}

int DvrReadBufferQueue::Dequeue(int timeout, DvrReadBuffer* read_buffer,
                                int* out_fence_fd, void* out_meta,
                                size_t meta_size_bytes) {
  if (meta_size_bytes != consumer_queue_->metadata_size()) {
    ALOGE(
        "DvrReadBufferQueue::Dequeue: Invalid metadata size, expected (%zu), "
        "but actual (%zu).",
        consumer_queue_->metadata_size(), meta_size_bytes);
    return -EINVAL;
  }

  size_t slot;
  pdx::LocalHandle acquire_fence;
  auto buffer_status = consumer_queue_->Dequeue(
      timeout, &slot, out_meta, meta_size_bytes, &acquire_fence);
  if (!buffer_status) {
    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
             "dvrReadBufferQueueDequeue: Failed to dequeue buffer: %s",
             buffer_status.GetErrorMessage().c_str());
    return -buffer_status.error();
  }

  read_buffer->read_buffer = buffer_status.take();
  *out_fence_fd = acquire_fence.Release();

  return 0;
}

int DvrReadBufferQueue::AcquireBuffer(int timeout,
                                      DvrReadBuffer** out_read_buffer,
                                      DvrNativeBufferMetadata* out_meta,
                                      int* out_fence_fd) {
  size_t slot;
  pdx::LocalHandle acquire_fence;
  auto buffer_status =
      consumer_queue_->Dequeue(timeout, &slot, out_meta, &acquire_fence);
  if (!buffer_status) {
    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
             "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer: %s",
             buffer_status.GetErrorMessage().c_str());
    return -buffer_status.error();
  }

  if (read_buffers_[slot] == nullptr) {
    // Lazy initialization of a read_buffers_ slot. Note that a slot will only
    // be dynamically allocated once during the entire cycle life of a queue.
    read_buffers_[slot] = std::make_unique<DvrReadBuffer>();
    read_buffers_[slot]->slot = slot;
  }

  LOG_FATAL_IF(
      read_buffers_[slot]->read_buffer,
      "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot);
  read_buffers_[slot]->read_buffer = std::move(buffer_status.take());

  *out_read_buffer = read_buffers_[slot].release();
  *out_fence_fd = acquire_fence.Release();

  return 0;
}

int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer,
                                      const DvrNativeBufferMetadata* meta,
                                      int release_fence_fd) {
  LOG_FATAL_IF(
      (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()),
      "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);

  // Some basic sanity checks before we put the buffer back into a slot.
  size_t slot = static_cast<size_t>(read_buffer->slot);
  if (read_buffers_[slot] != nullptr) {
    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot);
    return -EINVAL;
  }
  if (read_buffer->read_buffer == nullptr) {
    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer.");
    return -EINVAL;
  }
  if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) {
    ALOGE(
        "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released does not "
        "belong to this buffer queue. Releasing buffer: id=%d, buffer in "
        "queue: id=%d",
        read_buffer->read_buffer->id(), consumer_queue_->GetBufferId(slot));
    return -EINVAL;
  }

  pdx::LocalHandle fence(release_fence_fd);
  int ret = read_buffer->read_buffer->ReleaseAsync(meta, fence);
  if (ret < 0) {
    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d",
          ret);
    return ret;
  }

  // Put the DvrReadBuffer pointer back into its slot for reuse.
  read_buffers_[slot].reset(read_buffer);
  // It's import to reset the read buffer client now. It should stay invalid
  // until next AcquireBuffer on the same slot.
  read_buffers_[slot]->read_buffer = nullptr;
  return 0;
}

void DvrReadBufferQueue::SetBufferAvailableCallback(
    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
  if (callback == nullptr) {
    consumer_queue_->SetBufferAvailableCallback(nullptr);
  } else {
    consumer_queue_->SetBufferAvailableCallback(
        [callback, context]() { callback(context); });
  }
}

void DvrReadBufferQueue::SetBufferRemovedCallback(
    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
  if (callback == nullptr) {
    consumer_queue_->SetBufferRemovedCallback(nullptr);
  } else {
    consumer_queue_->SetBufferRemovedCallback(
        [callback, context](const std::shared_ptr<BufferHubBuffer>& buffer) {
          // When buffer is removed from the queue, the slot is already invalid.
          auto read_buffer = std::make_unique<DvrReadBuffer>();
          read_buffer->read_buffer =
              std::static_pointer_cast<BufferConsumer>(buffer);
          callback(read_buffer.release(), context);
        });
  }
}

int DvrReadBufferQueue::HandleEvents() {
  // TODO(jwcai) Probably should change HandleQueueEvents to return Status.
  consumer_queue_->HandleQueueEvents();
  return 0;
}

void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
  delete read_queue;
}

ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
  if (!read_queue)
    return -EINVAL;

  return read_queue->capacity();
}

int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) {
  if (!read_queue)
    return -EINVAL;

  return read_queue->id();
}

int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue) {
  if (!read_queue)
    return -EINVAL;

  return read_queue->event_fd();
}

int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
                                      DvrReadBufferQueue** out_read_queue) {
  if (!read_queue || !out_read_queue)
    return -EINVAL;

  return read_queue->CreateReadQueue(out_read_queue);
}

int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
                              DvrReadBuffer* read_buffer, int* out_fence_fd,
                              void* out_meta, size_t meta_size_bytes) {
  if (!read_queue || !read_buffer || !out_fence_fd)
    return -EINVAL;

  if (meta_size_bytes != 0 && !out_meta)
    return -EINVAL;

  return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta,
                             meta_size_bytes);
}

int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
                                    DvrReadBuffer** out_read_buffer,
                                    DvrNativeBufferMetadata* out_meta,
                                    int* out_fence_fd) {
  if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd)
    return -EINVAL;

  return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta,
                                   out_fence_fd);
}

int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
                                    DvrReadBuffer* read_buffer,
                                    const DvrNativeBufferMetadata* meta,
                                    int release_fence_fd) {
  if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta)
    return -EINVAL;

  return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd);
}

int dvrReadBufferQueueSetBufferAvailableCallback(
    DvrReadBufferQueue* read_queue,
    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
  if (!read_queue)
    return -EINVAL;

  read_queue->SetBufferAvailableCallback(callback, context);
  return 0;
}

int dvrReadBufferQueueSetBufferRemovedCallback(
    DvrReadBufferQueue* read_queue,
    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
  if (!read_queue)
    return -EINVAL;

  read_queue->SetBufferRemovedCallback(callback, context);
  return 0;
}

int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue) {
  if (!read_queue)
    return -EINVAL;

  return read_queue->HandleEvents();
}

}  // extern "C"
