/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 *
 * Image Processing Algorithm proxy for ipu3
 *
 * This file is auto-generated. Do not edit.
 */

#pragma once

#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipu3_ipa_interface.h>

#include <libcamera/base/object.h>
#include <libcamera/base/thread.h>

#include "libcamera/internal/control_serializer.h"
#include "libcamera/internal/ipa_proxy.h"
#include "libcamera/internal/ipc_pipe.h"
#include "libcamera/internal/ipc_pipe_unixsocket.h"
#include "libcamera/internal/ipc_unixsocket.h"

namespace libcamera {

namespace ipa {

namespace ipu3 {


class IPAProxyIPU3Threaded;
class IPAProxyIPU3Isolated;

class IPAProxyIPU3 : public IPAProxy, public IPAIPU3Interface, public Object
{
public:
	using Threaded = IPAProxyIPU3Threaded;
	using Isolated = IPAProxyIPU3Isolated;

protected:
	using IPAProxy::IPAProxy;
};

class IPAProxyIPU3Threaded : public IPAProxyIPU3
{
public:
	IPAProxyIPU3Threaded(IPAModule *ipam, const CameraManager &cm);
	~IPAProxyIPU3Threaded();


        int32_t init(
        	const IPASettings &settings,
        	const IPACameraSensorInfo &sensorInfo,
        	const ControlInfoMap &sensorControls,
        	ControlInfoMap *ipaControls) override;

        int32_t start() override;

        void stop() override;

        int32_t configure(
        	const IPAConfigInfo &configInfo,
        	ControlInfoMap *ipaControls) override;

        void mapBuffers(
        	const std::vector<libcamera::IPABuffer> &buffers) override;

        void unmapBuffers(
        	const std::vector<uint32_t> &ids) override;

        void queueRequest(
        	const uint32_t frame,
        	const ControlList &controls) override;

        void computeParams(
        	const uint32_t frame,
        	const uint32_t bufferId) override;

        void processStats(
        	const uint32_t frame,
        	const int64_t frameTimestamp,
        	const uint32_t bufferId,
        	const ControlList &sensorControls) override;


private:

        void setSensorControlsHandler(
        	const uint32_t frame,
        	const ControlList &sensorControls,
        	const ControlList &lensControls);

        void paramsComputedHandler(
        	const uint32_t frame);

        void metadataReadyHandler(
        	const uint32_t frame,
        	const ControlList &metadata);


	/* Helper class to invoke async functions in another thread. */
	class ThreadProxy : public Object
	{
	public:
		ThreadProxy()
			: ipa_(nullptr)
		{
		}

		void setIPA(IPAIPU3Interface *ipa)
		{
			ipa_ = ipa;
		}

		void stop()
		{
			ipa_->stop();
		}

		int32_t start()
		{
			return ipa_->start();
		}
		void queueRequest(
                	const uint32_t frame,
                	const ControlList &controls)
		{
			ipa_->queueRequest(frame, controls);
		}
		void computeParams(
                	const uint32_t frame,
                	const uint32_t bufferId)
		{
			ipa_->computeParams(frame, bufferId);
		}
		void processStats(
                	const uint32_t frame,
                	const int64_t frameTimestamp,
                	const uint32_t bufferId,
                	const ControlList &sensorControls)
		{
			ipa_->processStats(frame, frameTimestamp, bufferId, sensorControls);
		}

	private:
		IPAIPU3Interface *ipa_;
	};

	Thread thread_;
	ThreadProxy proxy_;
	std::unique_ptr<IPAIPU3Interface> ipa_;
};

class IPAProxyIPU3Isolated : public IPAProxyIPU3
{
public:
	IPAProxyIPU3Isolated(IPAModule *ipam, const CameraManager &cm);
	~IPAProxyIPU3Isolated();


        int32_t init(
        	const IPASettings &settings,
        	const IPACameraSensorInfo &sensorInfo,
        	const ControlInfoMap &sensorControls,
        	ControlInfoMap *ipaControls) override;

        int32_t start() override;

        void stop() override;

        int32_t configure(
        	const IPAConfigInfo &configInfo,
        	ControlInfoMap *ipaControls) override;

        void mapBuffers(
        	const std::vector<libcamera::IPABuffer> &buffers) override;

        void unmapBuffers(
        	const std::vector<uint32_t> &ids) override;

        void queueRequest(
        	const uint32_t frame,
        	const ControlList &controls) override;

        void computeParams(
        	const uint32_t frame,
        	const uint32_t bufferId) override;

        void processStats(
        	const uint32_t frame,
        	const int64_t frameTimestamp,
        	const uint32_t bufferId,
        	const ControlList &sensorControls) override;


private:
	void recvMessage(const IPCMessage &data);


	void setSensorControlsHandler(
		std::vector<uint8_t>::const_iterator data,
		size_t dataSize,
		const std::vector<SharedFD> &fds);

	void paramsComputedHandler(
		std::vector<uint8_t>::const_iterator data,
		size_t dataSize,
		const std::vector<SharedFD> &fds);

	void metadataReadyHandler(
		std::vector<uint8_t>::const_iterator data,
		size_t dataSize,
		const std::vector<SharedFD> &fds);


	std::unique_ptr<IPCPipeUnixSocket> ipc_;

	ControlSerializer controlSerializer_;


	uint32_t seq_;
};

} /* namespace ipu3 */

} /* namespace ipa */

} /* namespace libcamera */