#ifndef ASYNCHRONOUS_CONTINUATION_H
#define ASYNCHRONOUS_CONTINUATION_H

#include <functional>
#include <memory>
#include <componentThread.h>

namespace smo {

/**
 * AsynchronousContinuation - Template base class for async sequence management
 *
 * This template provides a common pattern for managing asynchronous operations
 * that need to maintain object lifetime through a sequence of callbacks.
 *
 * The template parameter OriginalCbFnT represents the signature of the original
 * callback that will be invoked when the async sequence completes.
 *
 * Usage:
 *   class MyAsyncReq
 *	 :	public AsynchronousContinuation<std::function<void(bool)>>
 *   {
 *   public:
 *     MyAsyncReq(std::function<void(bool)> originalCbFn)
 *     :	AsynchronousContinuation(originalCbFn)
 *    {}
 *
 *     // Segment methods take only the shared_ptr for lifetime management
 *     void myAsyncReq1(std::shared_ptr<MyAsyncReq> context);
 *     void myAsyncReq2(std::shared_ptr<MyAsyncReq> context);
 *   };
 */
template <class OriginalCbFnT>
class AsynchronousContinuation
{
public:
	explicit AsynchronousContinuation(OriginalCbFnT originalCbFn)
	: originalCbFn(std::move(originalCbFn))
	{}

	/**		EXPLANATION:
	 * Each numbered segmented sequence persists the lifetime of the
	 * continuation object by taking a copy of its shared_ptr.
	 */
	typedef void (SegmentFn)(
		std::shared_ptr<AsynchronousContinuation<OriginalCbFnT>>
			lifetimePreservingConveyance);

protected:
	OriginalCbFnT originalCbFn;
};

class ContinuationTarget
{
public:
	ContinuationTarget(
		const std::shared_ptr<ComponentThread> &caller)
	: caller(caller)
	{}

public:
	const std::shared_ptr<ComponentThread> caller;
};

template <class OriginalCbFnT>
class TargetedAsynchronousContinuation
:	public AsynchronousContinuation<OriginalCbFnT>, public ContinuationTarget
{
public:
	TargetedAsynchronousContinuation(
		const std::shared_ptr<ComponentThread> &caller,
		OriginalCbFnT originalCbFn)
	:	AsynchronousContinuation<OriginalCbFnT>(originalCbFn),
		ContinuationTarget(caller)
	{}
};

} // namespace smo

#endif // ASYNCHRONOUS_CONTINUATION_H
