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

#include <utility>

#include "hal/ip/request_queue.h"

#include <sync/sync.h>

#include "cros-camera/common.h"

namespace cros {

CaptureRequest::CaptureRequest(camera3_capture_request_t* request)
    : frame_number_(request->frame_number) {
  output_stream_buffer_.stream = request->output_buffers[0].stream;
  buffer_handle_ = *(request->output_buffers[0].buffer);
  output_stream_buffer_.buffer = &buffer_handle_;
  output_stream_buffer_.status = CAMERA3_BUFFER_STATUS_OK;
  output_stream_buffer_.acquire_fence =
      request->output_buffers[0].acquire_fence;
  output_stream_buffer_.release_fence = -1;
}

CaptureRequest::~CaptureRequest() {}

const uint32_t CaptureRequest::GetFrameNumber() const {
  return frame_number_;
}

const camera3_stream_buffer_t* CaptureRequest::GetOutputBuffer() const {
  return &output_stream_buffer_;
}

void CaptureRequest::SetErrorBufferStatus() {
  output_stream_buffer_.release_fence = output_stream_buffer_.acquire_fence;
  output_stream_buffer_.status = CAMERA3_BUFFER_STATUS_ERROR;
}

RequestQueue::RequestQueue()
    : lock_(),
      queue_(),
      new_request_available_(&lock_),
      request_filled_(&lock_),
      requests_being_filled_(0),
      flushing_(false),
      callback_ops_(nullptr) {}

RequestQueue::~RequestQueue() {
  base::AutoLock l(lock_);
  queue_.clear();
}

void RequestQueue::Push(camera3_capture_request_t* request) {
  base::AutoLock l(lock_);
  if (flushing_) {
    CancelRequestLocked(std::make_unique<CaptureRequest>(request));
  } else {
    queue_.push_back(std::make_unique<CaptureRequest>(request));
    new_request_available_.Signal();
  }
}

std::unique_ptr<CaptureRequest> RequestQueue::Pop() {
  std::unique_ptr<CaptureRequest> request = nullptr;
  {
    base::AutoLock l(lock_);
    if (flushing_) {
      return nullptr;
    }
    while (queue_.empty()) {
      new_request_available_.Wait();
    }
    request = std::move(queue_.front());
    requests_being_filled_++;
    queue_.pop_front();
  }

  const camera3_stream_buffer_t* buffer = request->GetOutputBuffer();
  if (buffer->acquire_fence != -1) {
    if (sync_wait(buffer->acquire_fence, 300)) {
      LOGF(ERROR) << "Timed out waiting on camera buffer acquire fence";
    }
  }

  struct timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  uint64_t timestamp = time.tv_sec * 1000000000LL + time.tv_nsec;
  NotifyShutter(request->GetFrameNumber(), timestamp);

  return request;
}

bool RequestQueue::IsEmpty() {
  base::AutoLock l(lock_);
  return queue_.empty();
}

void RequestQueue::Flush() {
  base::AutoLock l(lock_);
  flushing_ = true;
  while (requests_being_filled_ > 0) {
    request_filled_.Wait();
  }
  while (!queue_.empty()) {
    CancelRequestLocked(std::move(queue_.front()));
    queue_.pop_front();
  }
  flushing_ = false;
}

void RequestQueue::SetCallbacks(const camera3_callback_ops_t* callback_ops) {
  callback_ops_ = callback_ops;
}

void RequestQueue::NotifyShutter(uint32_t frame_number, uint64_t timestamp) {
  if (!callback_ops_) {
    LOGF(ERROR) << "Callbacks weren't set on the request queue.";
    return;
  }

  camera3_notify_msg_t msg = {};
  msg.type = CAMERA3_MSG_SHUTTER;
  msg.message.shutter.frame_number = frame_number;
  msg.message.shutter.timestamp = timestamp;
  callback_ops_->notify(callback_ops_, &msg);
}

void RequestQueue::NotifyCaptureInternal(
    std::unique_ptr<CaptureRequest> request) {
  if (!callback_ops_) {
    LOGF(ERROR) << "Callbacks weren't set on the request queue.";
    return;
  }

  camera3_capture_result_t result = {};
  result.frame_number = request->GetFrameNumber();
  result.result = nullptr;
  result.num_output_buffers = 1;
  result.output_buffers = request->GetOutputBuffer();
  result.partial_result = 1;
  callback_ops_->process_capture_result(callback_ops_, &result);
  // request goes out of scope and gets deleted at the end of this function
}

void RequestQueue::NotifyCapture(std::unique_ptr<CaptureRequest> request) {
  NotifyCaptureInternal(std::move(request));
  base::AutoLock l(lock_);
  requests_being_filled_--;
  request_filled_.Signal();
}

void RequestQueue::CancelRequestLocked(
    std::unique_ptr<CaptureRequest> request) {
  if (!callback_ops_) {
    LOGF(ERROR) << "Callbacks weren't set on the request queue.";
    return;
  }
  camera3_notify_msg_t msg = {};
  msg.type = CAMERA3_MSG_ERROR;
  msg.message.error.frame_number = request->GetFrameNumber();
  msg.message.error.error_stream = nullptr;
  msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
  callback_ops_->notify(callback_ops_, &msg);

  request->SetErrorBufferStatus();
  NotifyCaptureInternal(std::move(request));
}

void RequestQueue::NotifyError(std::unique_ptr<CaptureRequest> request) {
  base::AutoLock l(lock_);
  CancelRequestLocked(std::move(request));
  requests_being_filled_--;
  request_filled_.Signal();
}

}  // namespace cros
