/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2018, Google Inc.
 *
 * camera_manager.h - Camera management
 */

#include <libcamera/camera_manager.h>

#include <condition_variable>
#include <map>

#include <libcamera/camera.h>
#include <libcamera/event_dispatcher.h>

#include "device_enumerator.h"
#include "event_dispatcher_poll.h"
#include "log.h"
#include "pipeline_handler.h"
#include "thread.h"
#include "utils.h"

/**
 * \file camera_manager.h
 * \brief The camera manager
 */

namespace libcamera {

LOG_DEFINE_CATEGORY(Camera)

class CameraManager::Private : public Thread
{
public:
	Private(CameraManager *cm);

	int start();
	void addCamera(std::shared_ptr<Camera> &camera, dev_t devnum);
	void removeCamera(Camera *camera);

	/*
	 * This mutex protects
	 *
	 * - initialized_ and status_ during initialization
	 * - cameras_ and camerasByDevnum_ after initialization
	 */
	Mutex mutex_;
	std::vector<std::shared_ptr<Camera>> cameras_;
	std::map<dev_t, std::weak_ptr<Camera>> camerasByDevnum_;

protected:
	void run() override;

private:
	int init();
	void cleanup();

	CameraManager *cm_;

	std::condition_variable cv_;
	bool initialized_;
	int status_;

	std::vector<std::shared_ptr<PipelineHandler>> pipes_;
	std::unique_ptr<DeviceEnumerator> enumerator_;
};

CameraManager::Private::Private(CameraManager *cm)
	: cm_(cm), initialized_(false)
{
}

int CameraManager::Private::start()
{
	int status;

	/* Start the thread and wait for initialization to complete. */
	Thread::start();

	{
		MutexLocker locker(mutex_);
		cv_.wait(locker, [&] { return initialized_; });
		status = status_;
	}

	/* If a failure happened during initialization, stop the thread. */
	if (status < 0) {
		exit();
		wait();
		return status;
	}

	return 0;
}

void CameraManager::Private::run()
{
	LOG(Camera, Debug) << "Starting camera manager";

	int ret = init();

	mutex_.lock();
	status_ = ret;
	initialized_ = true;
	mutex_.unlock();
	cv_.notify_one();

	if (ret < 0)
		return;

	/* Now start processing events and messages. */
	exec();

	cleanup();
}

int CameraManager::Private::init()
{
	enumerator_ = DeviceEnumerator::create();
	if (!enumerator_ || enumerator_->enumerate())
		return -ENODEV;

	/*
	 * TODO: Try to read handlers and order from configuration
	 * file and only fallback on all handlers if there is no
	 * configuration file.
	 */
	std::vector<PipelineHandlerFactory *> &factories = PipelineHandlerFactory::factories();

	for (PipelineHandlerFactory *factory : factories) {
		/*
		 * Try each pipeline handler until it exhaust
		 * all pipelines it can provide.
		 */
		while (1) {
			std::shared_ptr<PipelineHandler> pipe = factory->create(cm_);
			if (!pipe->match(enumerator_.get()))
				break;

			LOG(Camera, Debug)
				<< "Pipeline handler \"" << factory->name()
				<< "\" matched";
			pipes_.push_back(std::move(pipe));
		}
	}

	/* TODO: register hot-plug callback here */

	return 0;
}

void CameraManager::Private::cleanup()
{
	/* TODO: unregister hot-plug callback here */

	/*
	 * Release all references to cameras and pipeline handlers to ensure
	 * they all get destroyed before the device enumerator deletes the
	 * media devices.
	 */
	pipes_.clear();
	cameras_.clear();

	enumerator_.reset(nullptr);
}

void CameraManager::Private::addCamera(std::shared_ptr<Camera> &camera,
				       dev_t devnum)
{
	MutexLocker locker(mutex_);

	for (std::shared_ptr<Camera> c : cameras_) {
		if (c->name() == camera->name()) {
			LOG(Camera, Warning)
				<< "Registering camera with duplicate name '"
				<< camera->name() << "'";
			break;
		}
	}

	cameras_.push_back(std::move(camera));

	if (devnum) {
		unsigned int index = cameras_.size() - 1;
		camerasByDevnum_[devnum] = cameras_[index];
	}
}

void CameraManager::Private::removeCamera(Camera *camera)
{
	MutexLocker locker(mutex_);

	auto iter = std::find_if(cameras_.begin(), cameras_.end(),
				 [camera](std::shared_ptr<Camera> &c) {
					 return c.get() == camera;
				 });
	if (iter == cameras_.end())
		return;

	LOG(Camera, Debug)
		<< "Unregistering camera '" << camera->name() << "'";

	auto iter_d = std::find_if(camerasByDevnum_.begin(), camerasByDevnum_.end(),
				   [camera](const std::pair<dev_t, std::weak_ptr<Camera>> &p) {
					   return p.second.lock().get() == camera;
				   });
	if (iter_d != camerasByDevnum_.end())
		camerasByDevnum_.erase(iter_d);

	cameras_.erase(iter);
}

/**
 * \class CameraManager
 * \brief Provide access and manage all cameras in the system
 *
 * The camera manager is the entry point to libcamera. It enumerates devices,
 * associates them with pipeline managers, and provides access to the cameras
 * in the system to applications. The manager owns all Camera objects and
 * handles hot-plugging and hot-unplugging to manage the lifetime of cameras.
 *
 * To interact with libcamera, an application starts by creating a camera
 * manager instance. Only a single instance of the camera manager may exist at
 * a time. Attempting to create a second instance without first deleting the
 * existing instance results in undefined behaviour.
 *
 * The manager is initially stopped, and shall be configured before being
 * started. In particular a custom event dispatcher shall be installed if
 * needed with CameraManager::setEventDispatcher().
 *
 * Once the camera manager is configured, it shall be started with start().
 * This will enumerate all the cameras present in the system, which can then be
 * listed with list() and retrieved with get().
 *
 * Cameras are shared through std::shared_ptr<>, ensuring that a camera will
 * stay valid until the last reference is released without requiring any special
 * action from the application. Once the application has released all the
 * references it held to cameras, the camera manager can be stopped with
 * stop().
 *
 * \todo Add interface to register a notification callback to the user to be
 * able to inform it new cameras have been hot-plugged or cameras have been
 * removed due to hot-unplug.
 */

CameraManager *CameraManager::self_ = nullptr;

CameraManager::CameraManager()
	: p_(new CameraManager::Private(this))
{
	if (self_)
		LOG(Camera, Fatal)
			<< "Multiple CameraManager objects are not allowed";

	self_ = this;
}

CameraManager::~CameraManager()
{
	stop();

	self_ = nullptr;
}

/**
 * \brief Start the camera manager
 *
 * Start the camera manager and enumerate all devices in the system. Once
 * the start has been confirmed the user is free to list and otherwise
 * interact with cameras in the system until either the camera manager
 * is stopped or the camera is unplugged from the system.
 *
 * \return 0 on success or a negative error code otherwise
 */
int CameraManager::start()
{
	LOG(Camera, Info) << "libcamera " << version_;

	int ret = p_->start();
	if (ret)
		LOG(Camera, Error) << "Failed to start camera manager: "
				   << strerror(-ret);

	return ret;
}

/**
 * \brief Stop the camera manager
 *
 * Before stopping the camera manager the caller is responsible for making
 * sure all cameras provided by the manager are returned to the manager.
 *
 * After the manager has been stopped no resource provided by the camera
 * manager should be consider valid or functional even if they for one
 * reason or another have yet to be deleted.
 */
void CameraManager::stop()
{
	p_->exit();
	p_->wait();
}

/**
 * \fn CameraManager::cameras()
 * \brief Retrieve all available cameras
 *
 * Before calling this function the caller is responsible for ensuring that
 * the camera manager is running.
 *
 * \context This function is \threadsafe.
 *
 * \return List of all available cameras
 */
std::vector<std::shared_ptr<Camera>> CameraManager::cameras() const
{
	MutexLocker locker(p_->mutex_);

	return p_->cameras_;
}

/**
 * \brief Get a camera based on name
 * \param[in] name Name of camera to get
 *
 * Before calling this function the caller is responsible for ensuring that
 * the camera manager is running.
 *
 * \context This function is \threadsafe.
 *
 * \return Shared pointer to Camera object or nullptr if camera not found
 */
std::shared_ptr<Camera> CameraManager::get(const std::string &name)
{
	MutexLocker locker(p_->mutex_);

	for (std::shared_ptr<Camera> camera : p_->cameras_) {
		if (camera->name() == name)
			return camera;
	}

	return nullptr;
}

/**
 * \brief Retrieve a camera based on device number
 * \param[in] devnum Device number of camera to get
 *
 * This method is meant solely for the use of the V4L2 compatibility
 * layer, to map device nodes to Camera instances. Applications shall
 * not use it and shall instead retrieve cameras by name.
 *
 * Before calling this function the caller is responsible for ensuring that
 * the camera manager is running.
 *
 * \context This function is \threadsafe.
 *
 * \return Shared pointer to Camera object, which is empty if the camera is
 * not found
 */
std::shared_ptr<Camera> CameraManager::get(dev_t devnum)
{
	MutexLocker locker(p_->mutex_);

	auto iter = p_->camerasByDevnum_.find(devnum);
	if (iter == p_->camerasByDevnum_.end())
		return nullptr;

	return iter->second.lock();
}

/**
 * \brief Add a camera to the camera manager
 * \param[in] camera The camera to be added
 * \param[in] devnum The device number to associate with \a camera
 *
 * This function is called by pipeline handlers to register the cameras they
 * handle with the camera manager. Registered cameras are immediately made
 * available to the system.
 *
 * \a devnum is used by the V4L2 compatibility layer to map V4L2 device nodes
 * to Camera instances.
 *
 * \context This function shall be called from the CameraManager thread.
 */
void CameraManager::addCamera(std::shared_ptr<Camera> camera, dev_t devnum)
{
	ASSERT(Thread::current() == p_.get());

	p_->addCamera(camera, devnum);
}

/**
 * \brief Remove a camera from the camera manager
 * \param[in] camera The camera to be removed
 *
 * This function is called by pipeline handlers to unregister cameras from the
 * camera manager. Unregistered cameras won't be reported anymore by the
 * cameras() and get() calls, but references may still exist in applications.
 *
 * \context This function shall be called from the CameraManager thread.
 */
void CameraManager::removeCamera(Camera *camera)
{
	ASSERT(Thread::current() == p_.get());

	p_->removeCamera(camera);
}

/**
 * \fn const std::string &CameraManager::version()
 * \brief Retrieve the libcamera version string
 * \context This function is \a threadsafe.
 * \return The libcamera version string
 */

/**
 * \brief Set the event dispatcher
 * \param[in] dispatcher Pointer to the event dispatcher
 *
 * libcamera requires an event dispatcher to integrate event notification and
 * timers with the application event loop. Applications that want to provide
 * their own event dispatcher shall call this function once and only once before
 * the camera manager is started with start(). If no event dispatcher is
 * provided, a default poll-based implementation will be used.
 *
 * The CameraManager takes ownership of the event dispatcher and will delete it
 * when the application terminates.
 */
void CameraManager::setEventDispatcher(std::unique_ptr<EventDispatcher> dispatcher)
{
	thread()->setEventDispatcher(std::move(dispatcher));
}

/**
 * \brief Retrieve the event dispatcher
 *
 * This function retrieves the event dispatcher set with setEventDispatcher().
 * If no dispatcher has been set, a default poll-based implementation is created
 * and returned, and no custom event dispatcher may be installed anymore.
 *
 * The returned event dispatcher is valid until the camera manager is destroyed.
 *
 * \return Pointer to the event dispatcher
 */
EventDispatcher *CameraManager::eventDispatcher()
{
	return thread()->eventDispatcher();
}

} /* namespace libcamera */
