/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * request.cpp - Capture request handling
 */

#include "libcamera/internal/request.h"

#include <map>
#include <sstream>

#include <libcamera/base/log.h>

#include <libcamera/camera.h>
#include <libcamera/control_ids.h>
#include <libcamera/fence.h>
#include <libcamera/framebuffer.h>
#include <libcamera/stream.h>

#include "libcamera/internal/camera.h"
#include "libcamera/internal/camera_controls.h"
#include "libcamera/internal/framebuffer.h"
#include "libcamera/internal/tracepoints.h"

/**
 * \file libcamera/request.h
 * \brief Describes a frame capture request to be processed by a camera
 */

namespace libcamera {

LOG_DEFINE_CATEGORY(Request)

/**
 * \class Request::Private
 * \brief Request private data
 *
 * The Request::Private class stores all private data associated with a
 * request. It implements the d-pointer design pattern to hide core
 * Request data from the public API, and exposes utility functions to
 * internal users of the request (namely the PipelineHandler class and its
 * subclasses).
 */

/**
 * \brief Create a Request::Private
 * \param camera The Camera that creates the request
 */
Request::Private::Private(Camera *camera)
	: camera_(camera), cancelled_(false)
{
}

Request::Private::~Private()
{
	doCancelRequest();
}

/**
 * \fn Request::Private::camera()
 * \brief Retrieve the camera this request has been queued to
 * \return The Camera this request has been queued to, or nullptr if the
 * request hasn't been queued
 */

/**
 * \brief Check if a request has buffers yet to be completed
 *
 * \return True if the request has buffers pending for completion, false
 * otherwise
 */
bool Request::Private::hasPendingBuffers() const
{
	return !pending_.empty();
}

/**
 * \brief Complete a buffer for the request
 * \param[in] buffer The buffer that has completed
 *
 * A request tracks the status of all buffers it contains through a set of
 * pending buffers. This function removes the \a buffer from the set to mark it
 * as complete. All buffers associate with the request shall be marked as
 * complete by calling this function once and once only before reporting the
 * request as complete with the complete() function.
 *
 * \return True if all buffers contained in the request have completed, false
 * otherwise
 */
bool Request::Private::completeBuffer(FrameBuffer *buffer)
{
	LIBCAMERA_TRACEPOINT(request_complete_buffer, this, buffer);

	int ret = pending_.erase(buffer);
	ASSERT(ret == 1);

	buffer->_d()->setRequest(nullptr);

	if (buffer->metadata().status == FrameMetadata::FrameCancelled)
		cancelled_ = true;

	return !hasPendingBuffers();
}

/**
 * \brief Complete a queued request
 *
 * Mark the request as complete by updating its status to RequestComplete,
 * unless buffers have been cancelled in which case the status is set to
 * RequestCancelled.
 */
void Request::Private::complete()
{
	Request *request = _o<Request>();

	ASSERT(request->status() == RequestPending);
	ASSERT(!hasPendingBuffers());

	request->status_ = cancelled_ ? RequestCancelled : RequestComplete;

	LOG(Request, Debug) << request->toString();

	LIBCAMERA_TRACEPOINT(request_complete, this);
}

void Request::Private::doCancelRequest()
{
	Request *request = _o<Request>();

	for (FrameBuffer *buffer : pending_) {
		buffer->cancel();
		camera_->bufferCompleted.emit(request, buffer);
	}

	cancelled_ = true;
	pending_.clear();
	notifiers_.clear();
	timer_.reset();
}

/**
 * \brief Cancel a queued request
 *
 * Mark the request and its associated buffers as cancelled and complete it.
 *
 * Set each pending buffer in error state and emit the buffer completion signal
 * before completing the Request.
 */
void Request::Private::cancel()
{
	LIBCAMERA_TRACEPOINT(request_cancel, this);

	Request *request = _o<Request>();
	ASSERT(request->status() == RequestPending);

	doCancelRequest();
}

/**
 * \copydoc Request::reuse()
 */
void Request::Private::reuse()
{
	sequence_ = 0;
	cancelled_ = false;
	prepared_ = false;
	pending_.clear();
	notifiers_.clear();
	timer_.reset();
}

/*
 * Helper function to save some lines of code and make sure prepared_ is set
 * to true before emitting the signal.
 */
void Request::Private::emitPrepareCompleted()
{
	prepared_ = true;
	prepared.emit();
}

/**
 * \brief Prepare the Request to be queued to the device
 * \param[in] timeout Optional expiration timeout
 *
 * Prepare a Request to be queued to the hardware device by ensuring it is
 * ready for the incoming memory transfers.
 *
 * This currently means waiting on each frame buffer acquire fence to be
 * signalled. An optional expiration timeout can be specified. If not all the
 * fences have been signalled correctly before the timeout expires the Request
 * is cancelled.
 *
 * The function immediately emits the prepared signal if all the prepare
 * operations have been completed synchronously. If instead the prepare
 * operations require to wait the completion of asynchronous events, such as
 * fences notifications or timer expiration, the prepared signal is emitted upon
 * the asynchronous event completion.
 *
 * As we currently only handle fences, the function emits the prepared signal
 * immediately if there are no fences to wait on. Otherwise the prepared signal
 * is emitted when all fences have been signalled or the optional timeout has
 * expired.
 *
 * If not all the fences have been correctly signalled or the optional timeout
 * has expired the Request will be cancelled and the Request::prepared signal
 * emitted.
 *
 * The intended user of this function is the PipelineHandler base class, which
 * 'prepares' a Request before queuing it to the hardware device.
 */
void Request::Private::prepare(std::chrono::milliseconds timeout)
{
	/* Create and connect one notifier for each synchronization fence. */
	for (FrameBuffer *buffer : pending_) {
		const Fence *fence = buffer->_d()->fence();
		if (!fence)
			continue;

		std::unique_ptr<EventNotifier> notifier =
			std::make_unique<EventNotifier>(fence->fd().get(),
							EventNotifier::Read);

		notifier->activated.connect(this, [this, buffer] {
							notifierActivated(buffer);
					    });

		notifiers_[buffer] = std::move(notifier);
	}

	if (notifiers_.empty()) {
		emitPrepareCompleted();
		return;
	}

	/*
	 * In case a timeout is specified, create a timer and set it up.
	 *
	 * The timer must be created here instead of in the Request constructor,
	 * in order to be bound to the pipeline handler thread.
	 */
	if (timeout != 0ms) {
		timer_ = std::make_unique<Timer>();
		timer_->timeout.connect(this, &Request::Private::timeout);
		timer_->start(timeout);
	}
}

/**
 * \var Request::Private::prepared
 * \brief Request preparation completed Signal
 *
 * The signal is emitted once the request preparation has completed and is ready
 * to be queued. The Request might complete with errors in which case it is
 * cancelled.
 *
 * The intended slot for this signal is the PipelineHandler::doQueueRequests()
 * function which queues Request after they have been prepared or cancel them
 * if they have failed preparing.
 */

void Request::Private::notifierActivated(FrameBuffer *buffer)
{
	/* Close the fence if successfully signalled. */
	ASSERT(buffer);
	buffer->releaseFence();

	/* Remove the entry from the map and check if other fences are pending. */
	auto it = notifiers_.find(buffer);
	ASSERT(it != notifiers_.end());
	notifiers_.erase(it);

	Request *request = _o<Request>();
	LOG(Request, Debug)
		<< "Request " << request->cookie() << " buffer " << buffer
		<< " fence signalled";

	if (!notifiers_.empty())
		return;

	/* All fences completed, delete the timer and emit the prepared signal. */
	timer_.reset();
	emitPrepareCompleted();
}

void Request::Private::timeout()
{
	/* A timeout can only happen if there are fences not yet signalled. */
	ASSERT(!notifiers_.empty());
	notifiers_.clear();

	Request *request = _o<Request>();
	LOG(Request, Debug) << "Request prepare timeout: " << request->cookie();

	cancel();

	emitPrepareCompleted();
}

/**
 * \enum Request::Status
 * Request completion status
 * \var Request::RequestPending
 * The request hasn't completed yet
 * \var Request::RequestComplete
 * The request has completed
 * \var Request::RequestCancelled
 * The request has been cancelled due to capture stop
 */

/**
 * \enum Request::ReuseFlag
 * Flags to control the behavior of Request::reuse()
 * \var Request::Default
 * Don't reuse buffers
 * \var Request::ReuseBuffers
 * Reuse the buffers that were previously added by addBuffer()
 */

/**
 * \typedef Request::BufferMap
 * \brief A map of Stream to FrameBuffer pointers
 */

/**
 * \class Request
 * \brief A frame capture request
 *
 * A Request allows an application to associate buffers and controls on a
 * per-frame basis to be queued to the camera device for processing.
 */

/**
 * \brief Create a capture request for a camera
 * \param[in] camera The camera that creates the request
 * \param[in] cookie Opaque cookie for application use
 *
 * The \a cookie is stored in the request and is accessible through the
 * cookie() function at any time. It is typically used by applications to map
 * the request to an external resource in the request completion handler, and is
 * completely opaque to libcamera.
 */
Request::Request(Camera *camera, uint64_t cookie)
	: Extensible(std::make_unique<Private>(camera)),
	  cookie_(cookie), status_(RequestPending)
{
	controls_ = new ControlList(controls::controls,
				    camera->_d()->validator());

	/**
	 * \todo: Add a validator for metadata controls.
	 */
	metadata_ = new ControlList(controls::controls);

	LIBCAMERA_TRACEPOINT(request_construct, this);

	LOG(Request, Debug) << "Created request - cookie: " << cookie_;
}

Request::~Request()
{
	LIBCAMERA_TRACEPOINT(request_destroy, this);

	delete metadata_;
	delete controls_;
}

/**
 * \brief Reset the request for reuse
 * \param[in] flags Indicate whether or not to reuse the buffers
 *
 * Reset the status and controls associated with the request, to allow it to
 * be reused and requeued without destruction. This function shall be called
 * prior to queueing the request to the camera, in lieu of constructing a new
 * request. The application can reuse the buffers that were previously added
 * to the request via addBuffer() by setting \a flags to ReuseBuffers.
 */
void Request::reuse(ReuseFlag flags)
{
	LIBCAMERA_TRACEPOINT(request_reuse, this);

	_d()->reuse();

	if (flags & ReuseBuffers) {
		for (auto pair : bufferMap_) {
			FrameBuffer *buffer = pair.second;
			buffer->_d()->setRequest(this);
			_d()->pending_.insert(buffer);
		}
	} else {
		bufferMap_.clear();
	}

	status_ = RequestPending;

	controls_->clear();
	metadata_->clear();
}

/**
 * \fn Request::controls()
 * \brief Retrieve the request's ControlList
 *
 * Requests store a list of controls to be applied to all frames captured for
 * the request. They are created with an empty list of controls that can be
 * accessed through this function. Control values can be retrieved using
 * ControlList::get() and updated using ControlList::set().
 *
 * Only controls supported by the camera to which this request will be
 * submitted shall be included in the controls list. Attempting to add an
 * unsupported control causes undefined behaviour.
 *
 * \return A reference to the ControlList in this request
 */

/**
 * \fn Request::buffers()
 * \brief Retrieve the request's streams to buffers map
 *
 * Return a reference to the map that associates each Stream part of the
 * request to the FrameBuffer the Stream output should be directed to.
 *
 * \return The map of Stream to FrameBuffer
 */

/**
 * \brief Add a FrameBuffer with its associated Stream to the Request
 * \param[in] stream The stream the buffer belongs to
 * \param[in] buffer The FrameBuffer to add to the request
 * \param[in] fence The optional fence
 *
 * A reference to the buffer is stored in the request. The caller is responsible
 * for ensuring that the buffer will remain valid until the request complete
 * callback is called.
 *
 * A request can only contain one buffer per stream. If a buffer has already
 * been added to the request for the same stream, this function returns -EEXIST.
 *
 * A Fence can be optionally associated with the \a buffer.
 *
 * When a valid Fence is provided to this function, \a fence is moved to \a
 * buffer and this Request will only be queued to the device once the
 * fences of all its buffers have been correctly signalled.
 *
 * If the \a fence associated with \a buffer isn't signalled, the request will
 * fail after a timeout. The buffer will still contain the fence, which
 * applications must retrieve with FrameBuffer::releaseFence() before the buffer
 * can be reused in another request. Attempting to add a buffer that still
 * contains a fence to a request will result in this function returning -EEXIST.
 *
 * \sa FrameBuffer::releaseFence()
 *
 * \return 0 on success or a negative error code otherwise
 * \retval -EEXIST The request already contains a buffer for the stream
 *  or the buffer still references a fence
 * \retval -EINVAL The buffer does not reference a valid Stream
 */
int Request::addBuffer(const Stream *stream, FrameBuffer *buffer,
		       std::unique_ptr<Fence> fence)
{
	if (!stream) {
		LOG(Request, Error) << "Invalid stream reference";
		return -EINVAL;
	}

	auto it = bufferMap_.find(stream);
	if (it != bufferMap_.end()) {
		LOG(Request, Error) << "FrameBuffer already set for stream";
		return -EEXIST;
	}

	buffer->_d()->setRequest(this);
	_d()->pending_.insert(buffer);
	bufferMap_[stream] = buffer;

	/*
	 * Make sure the fence has been extracted from the buffer
	 * to avoid waiting on a stale fence.
	 */
	if (buffer->_d()->fence()) {
		LOG(Request, Error) << "Can't add buffer that still references a fence";
		return -EEXIST;
	}

	if (fence && fence->isValid())
		buffer->_d()->setFence(std::move(fence));

	return 0;
}

/**
 * \var Request::bufferMap_
 * \brief Mapping of streams to buffers for this request
 *
 * The bufferMap_ tracks the buffers associated with each stream. If a stream is
 * not utilised in this request there will be no buffer for that stream in the
 * map.
 */

/**
 * \brief Return the buffer associated with a stream
 * \param[in] stream The stream the buffer is associated to
 * \return The buffer associated with the stream, or nullptr if the stream is
 * not part of this request
 */
FrameBuffer *Request::findBuffer(const Stream *stream) const
{
	const auto it = bufferMap_.find(stream);
	if (it == bufferMap_.end())
		return nullptr;

	return it->second;
}

/**
 * \fn Request::metadata()
 * \brief Retrieve the request's metadata
 * \todo Offer a read-only API towards applications while keeping a read/write
 * API internally.
 * \return The metadata associated with the request
 */

/**
 * \brief Retrieve the sequence number for the request
 *
 * When requests are queued, they are given a sequential number to track the
 * order in which requests are queued to a camera. This number counts all
 * requests given to a camera through its lifetime, and is not reset to zero
 * between camera stop/start sequences.
 *
 * It can be used to support debugging and identifying the flow of requests
 * through a pipeline, but does not guarantee to represent the sequence number
 * of any images in the stream. The sequence number is stored as an unsigned
 * integer and will wrap when overflowed.
 *
 * \return The request sequence number
 */
uint32_t Request::sequence() const
{
	return _d()->sequence_;
}

/**
 * \fn Request::cookie()
 * \brief Retrieve the cookie set when the request was created
 * \return The request cookie
 */

/**
 * \fn Request::status()
 * \brief Retrieve the request completion status
 *
 * The request status indicates whether the request has completed successfully
 * or with an error. When requests are created and before they complete the
 * request status is set to RequestPending, and is updated at completion time
 * to RequestComplete. If a request is cancelled at capture stop before it has
 * completed, its status is set to RequestCancelled.
 *
 * \return The request completion status
 */

/**
 * \brief Check if a request has buffers yet to be completed
 *
 * \return True if the request has buffers pending for completion, false
 * otherwise
 */
bool Request::hasPendingBuffers() const
{
	return !_d()->pending_.empty();
}

/**
 * \brief Generate a string representation of the Request internals
 *
 * This function facilitates debugging of Request state while it is used
 * internally within libcamera.
 *
 * \return A string representing the current state of the request
 */
std::string Request::toString() const
{
	std::stringstream ss;

	/* Pending, Completed, Cancelled(X). */
	static const char *statuses = "PCX";

	/* Example Output: Request(55:P:1/2:6523524) */
	ss << "Request(" << sequence() << ":" << statuses[status_] << ":"
	   << _d()->pending_.size() << "/" << bufferMap_.size() << ":"
	   << cookie_ << ")";

	return ss.str();
}

} /* namespace libcamera */
