/*
 * Copyright (c) 2019 Peter Bigot Consulting, LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_SYS_ONOFF_H_
#define ZEPHYR_INCLUDE_SYS_ONOFF_H_

#include <kernel.h>
#include <zephyr/types.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup resource_mgmt_apis Resource Management APIs
 * @ingroup kernel_apis
 * @{
 */

/**
 * @brief Flag fields used to specify on-off service behavior.
 */
enum onoff_service_flags {
	/**
	 * @brief Flag passed to onoff_service_init().
	 *
	 * When provided this indicates the start transition function
	 * may cause the calling thread to wait.  This blocks attempts
	 * to initiate a transition from a non-thread context.
	 */
	ONOFF_SERVICE_START_SLEEPS      = BIT(0),

	/**
	 * @brief Flag passed to onoff_service_init().
	 *
	 * As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
	 * stop transition function.
	 */
	ONOFF_SERVICE_STOP_SLEEPS       = BIT(1),

	/**
	 * @brief Flag passed to onoff_service_init().
	 *
	 * As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
	 * reset transition function.
	 */
	ONOFF_SERVICE_RESET_SLEEPS      = BIT(2),

	/* Internal use. */
	ONOFF_SERVICE_HAS_ERROR         = BIT(3),

	/* This and higher bits reserved for internal use. */
	ONOFF_SERVICE_INTERNAL_BASE     = BIT(4),
};

/* Forward declaration */
struct onoff_service;

/**
 * @brief Signature used to notify an on-off service that a transition
 * has completed.
 *
 * Functions of this type are passed to service-specific transition
 * functions to be used to report the completion of the operation.
 * The functions may be invoked from any context.
 *
 * @param srv the service for which transition was requested.
 *
 * @param res the result of the transition.  This shall be
 * non-negative on success, or a negative error code.  If an error is
 * indicated the service shall enter an error state.
 */
typedef void (*onoff_service_notify_fn)(struct onoff_service *srv,
					int res);

/**
 * @brief Signature used by service implementations to effect a
 * transition.
 *
 * Service definitions use two function pointers of this type to be
 * notified that a transition is required, and a third optional one to
 * reset service state.
 *
 * The start function will be called only from the off state.
 *
 * The stop function will be called only from the on state.
 *
 * The reset function may be called only when
 * onoff_service_has_error() returns true.
 *
 * @param srv the service for which transition was requested.
 *
 * @param notify the function to be invoked when the transition has
 * completed.  The callee shall capture this parameter to notify on
 * completion of asynchronous transitions.  If the transition is not
 * asynchronous, notify shall be invoked before the transition
 * function returns.
 */
typedef void (*onoff_service_transition_fn)(struct onoff_service *srv,
					    onoff_service_notify_fn notify);

/**
 * @brief State associated with an on-off service.
 *
 * No fields in this structure are intended for use by service
 * providers or clients.  The state is to be initialized once, using
 * onoff_service_init(), when the service provider is initialized.
 * In case of error it may be reset through the
 * onoff_service_reset() API.
 */
struct onoff_service {
	/* List of clients waiting for completion of reset or
	 * transition to on.
	 */
	sys_slist_t clients;

	/* Function to invoke to transition the service to on. */
	onoff_service_transition_fn start;

	/* Function to invoke to transition the service to off. */
	onoff_service_transition_fn stop;

	/* Function to force the service state to reset, where
	 * supported.
	 */
	onoff_service_transition_fn reset;

	/* Mutex protection for flags, clients, releaser, and refs. */
	struct k_spinlock lock;

	/* Client to be informed when transition to off completes. */
	struct onoff_client *releaser;

	/* Flags identifying the service state. */
	u16_t flags;

	/* Number of active clients for the service. */
	u16_t refs;
};

/** @internal */
#define ONOFF_SERVICE_INITIALIZER(_start, _stop, _reset, _flags) { \
		.start = _start,				   \
		.stop = _stop,					   \
		.reset = _reset,				   \
		.flags = _flags,				   \
}

/**
 * @brief Initialize an on-off service to off state.
 *
 * This function must be invoked exactly once per service instance, by
 * the infrastructure that provides the service, and before any other
 * on-off service API is invoked on the service.
 *
 * This function should never be invoked by clients of an on-off service.
 *
 * @param srv the service definition object to be initialized.
 *
 * @param start the function used to (initiate a) transition from off
 * to on.  This must not be null.  Include @ref ONOFF_SERVICE_START_SLEEPS as
 * appropriate in flags.
 *
 * @param stop the function used to (initiate a) transition from on to
 * off.  This must not be null.  Include @ref ONOFF_SERVICE_STOP_SLEEPS
 * as appropriate in flags.
 *
 * @param reset the function used to clear errors and force the
 * service to an off state.  Pass null if the service cannot or need
 * not be reset.  (Services where a transition operation can complete
 * with an error notification should support the reset operation.)
 * Include @ref ONOFF_SERVICE_RESET_SLEEPS as appropriate in flags.
 *
 * @param flags any or all of the flags mentioned above,
 * e.g. @ref ONOFF_SERVICE_START_SLEEPS.  Use of other flags produces an
 * error.
 *
 * @retval 0 on success
 * @retval -EINVAL if start, stop, or flags are invalid
 */
int onoff_service_init(struct onoff_service *srv,
		       onoff_service_transition_fn start,
		       onoff_service_transition_fn stop,
		       onoff_service_transition_fn reset,
		       u32_t flags);

/** @internal
 *
 * Flag fields used to specify on-off client behavior.
 *
 * These flags control whether calls to onoff_service_request() and
 * onoff_service_release() are synchronous or asynchronous, and for
 * asynchronous operations how the operation result is communicated to
 * the client.
 */
enum onoff_client_flags {
	/* Known-invalid field, used in validation */
	ONOFF_CLIENT_NOTIFY_INVALID     = 0,

	/*
	 * Indicates that no notification will be provided.
	 *
	 * Callers must check for completions using
	 * onoff_client_fetch_result().
	 *
	 * See onoff_client_init_spinwait().
	 */
	ONOFF_CLIENT_NOTIFY_SPINWAIT    = 1,

	/*
	 * Select notification through @ref k_poll signal
	 *
	 * See onoff_client_init_signal().
	 */
	ONOFF_CLIENT_NOTIFY_SIGNAL      = 2,

	/**
	 * Select notification through a user-provided callback.
	 *
	 * See onoff_client_init_callback().
	 */
	ONOFF_CLIENT_NOTIFY_CALLBACK    = 3,
};

/* Forward declaration */
struct onoff_client;

/**
 * @brief Signature used to notify an on-off service client of the
 * completion of an operation.
 *
 * These functions may be invoked from any context including
 * pre-kernel, ISR, or cooperative or pre-emptible threads.
 * Compatible functions must be isr-callable and non-suspendable.
 *
 * @param srv the service for which the operation was initiated.
 *
 * @param cli the client structure passed to the function that
 * initiated the operation.
 *
 * @param user_data user data provided when the client structure was
 * initialized with onoff_client_init_callback().
 *
 * @param res the result of the operation.  Expected values are
 * service-specific, but the value shall be non-negative if the
 * operation succeeded, and negative if the operation failed.
 */
typedef void (*onoff_client_callback)(struct onoff_service *srv,
				      struct onoff_client *cli,
				      void *user_data,
				      int res);

/**
 * @brief State associated with a client of an on-off service.
 *
 * Objects of this type are allocated by a client, which must use an
 * initialization function (e.g. onoff_client_init_signal()) to
 * configure them.
 *
 * Control of the object content transfers to the service provider
 * when a pointer to the object is passed to any on-off service
 * function.  While the service provider controls the object the
 * client must not change any object fields.  Control reverts to the
 * client:
 * * if the call to the service API returns an error;
 * * if the call to the service API succeeds for a no-wait operation;
 * * when operation completion is posted (signalled or callback
 *   invoked).
 *
 * After control has reverted to the client the state object must be
 * reinitialized for the next operation.
 *
 * The content of this structure is not public API: all configuration
 * and inspection should be done with functions like
 * onoff_client_init_callback() and onoff_client_fetch_result().
 */
struct onoff_client {
	/* Links the client into the set of waiting service users. */
	sys_snode_t node;

	union async {
		/* Pointer to signal used to notify client.
		 *
		 * The signal value corresponds to the res parameter
		 * of onoff_client_callback.
		 */
		struct k_poll_signal *signal;

		/* Handler and argument for callback notification. */
		struct callback {
			onoff_client_callback handler;
			void *user_data;
		} callback;
	} async;

	/*
	 * The result of the operation.
	 *
	 * This is the value that was (or would be) passed to the
	 * async infrastructure.  This field is the sole record of
	 * success or failure for no-wait synchronous operations.
	 */
	int volatile result;

	/* Flags recording client state. */
	u32_t volatile flags;
};

/**
 * @brief Check for and read the result of an asynchronous operation.
 *
 * @param op pointer to the object used to specify asynchronous
 * function behavior and store completion information.
 *
 * @param result pointer to storage for the result of the operation.
 * The result is stored only if the operation has completed.
 *
 * @retval 0 if the operation has completed.
 * @retval -EAGAIN if the operation has not completed.
 */
static inline int onoff_client_fetch_result(const struct onoff_client *op,
					    int *result)
{
	__ASSERT_NO_MSG(op != NULL);
	__ASSERT_NO_MSG(result != NULL);

	int rv = -EAGAIN;

	if (op->flags == 0U) {
		rv = 0;
		*result = op->result;
	}
	return rv;
}

/**
 * @brief Initialize an on-off client to be used for a spin-wait
 * operation notification.
 *
 * Clients that use this initialization receive no asynchronous
 * notification, and instead must periodically check for completion
 * using onoff_client_fetch_result().
 *
 * On completion of the operation the client object must be
 * reinitialized before it can be re-used.
 *
 * @param cli pointer to the client state object.
 */
static inline void onoff_client_init_spinwait(struct onoff_client *cli)
{
	__ASSERT_NO_MSG(cli != NULL);

	*cli = (struct onoff_client){
		.flags = ONOFF_CLIENT_NOTIFY_SPINWAIT,
	};
}

/**
 * @brief Initialize an on-off client to be used for a signal
 * operation notification.
 *
 * Clients that use this initialization will be notified of the
 * completion of operations submitted through onoff_request() and
 * onoff_release() through the provided signal.
 *
 * On completion of the operation the client object must be
 * reinitialized before it can be re-used.
 *
 * @note
 *   @rst
 *   This capability is available only when :option:`CONFIG_POLL` is
 *   selected.
 *   @endrst
 *
 * @param cli pointer to the client state object.
 *
 * @param sigp pointer to the signal to use for notification.  The
 * value must not be null.  The signal must be reset before the client
 * object is passed to the on-off service API.
 */
static inline void onoff_client_init_signal(struct onoff_client *cli,
					    struct k_poll_signal *sigp)
{
	__ASSERT_NO_MSG(cli != NULL);
	__ASSERT_NO_MSG(sigp != NULL);

	*cli = (struct onoff_client){
#ifdef CONFIG_POLL
		.async = {
			.signal = sigp,
		},
#endif /* CONFIG_POLL */
		.flags = ONOFF_CLIENT_NOTIFY_SIGNAL,
	};
}

/**
 * @brief Initialize an on-off client to be used for a callback
 * operation notification.
 *
 * Clients that use this initialization will be notified of the
 * completion of operations submitted through on-off service API
 * through the provided callback.  Note that callbacks may be invoked
 * from various contexts depending on the specific service; see
 * @ref onoff_client_callback.
 *
 * On completion of the operation the client object must be
 * reinitialized before it can be re-used.
 *
 * @param cli pointer to the client state object.
 *
 * @param handler a function pointer to use for notification.
 *
 * @param user_data an opaque pointer passed to the handler to provide
 * additional context.
 */
static inline void onoff_client_init_callback(struct onoff_client *cli,
					      onoff_client_callback handler,
					      void *user_data)
{
	__ASSERT_NO_MSG(cli != NULL);
	__ASSERT_NO_MSG(handler != NULL);

	*cli = (struct onoff_client){
		.async = {
			.callback = {
				.handler = handler,
				.user_data = user_data,
			},
		},
		.flags = ONOFF_CLIENT_NOTIFY_CALLBACK,
	};
}

/**
 * @brief Request a reservation to use an on-off service.
 *
 * The return value indicates the success or failure of an attempt to
 * initiate an operation to request the resource be made available.
 * If initiation of the operation succeeds the result of the request
 * operation is provided through the configured client notification
 * method, possibly before this call returns.
 *
 * Note that the call to this function may succeed in a case where the
 * actual request fails.  Always check the operation completion
 * result.
 *
 * As a specific example: A call to this function may succeed at a
 * point while the service is still transitioning to off due to a
 * previous call to onoff_release().  When the transition completes
 * the service would normally start a transition to on.  However, if
 * the transition to off completed in a non-thread context, and the
 * transition to on can sleep, the transition cannot be started and
 * the request will fail with `-EWOULDBLOCK`.
 *
 * @param srv the service that will be used.
 *
 * @param cli a non-null pointer to client state providing
 * instructions on synchronous expectations and how to notify the
 * client when the request completes.  Behavior is undefined if client
 * passes a pointer object associated with an incomplete service
 * operation.
 *
 * @retval Non-negative on successful (initiation of) request
 * @retval -EIO if service has recorded an an error
 * @retval -EINVAL if the parameters are invalid
 * @retval -EAGAIN if the reference count would overflow
 * @retval -EWOULDBLOCK if the function was invoked from non-thread
 * context and successful initiation could result in an attempt to
 * make the calling thread sleep.
 */
int onoff_request(struct onoff_service *srv,
		  struct onoff_client *cli);

/**
 * @brief Release a reserved use of an on-off service.
 *
 * The return value indicates the success or failure of an attempt to
 * initiate an operation to release the resource.  If initiation of
 * the operation succeeds the result of the release operation itself
 * is provided through the configured client notification method,
 * possibly before this call returns.
 *
 * Note that the call to this function may succeed in a case where the
 * actual release fails.  Always check the operation completion
 * result.
 *
 * @param srv the service that will be used.
 *
 * @param cli a non-null pointer to client state providing
 * instructions on how to notify the client when release completes.
 * Behavior is undefined if cli references an object associated with
 * an incomplete service operation.
 *
 * @retval Non-negative on successful (initiation of) release
 * @retval -EINVAL if the parameters are invalid
 * @retval -EIO if service has recorded an an error
 * @retval -EWOULDBLOCK if a non-blocking request was made and
 *         could not be satisfied without potentially blocking.
 * @retval -EALREADY if the service is already off or transitioning
 *         to off
 * @retval -EBUSY if the service is transitioning to on
 */
int onoff_release(struct onoff_service *srv,
		  struct onoff_client *cli);

/**
 * @brief Test whether an on-off service has recorded an error.
 *
 * This function can be used to determine whether the service has
 * recorded an error.  Errors may be cleared by invoking
 * onoff_service_reset().
 *
 * @return true if and only if the service has an uncleared error.
 */
static inline bool onoff_service_has_error(const struct onoff_service *srv)
{
	return (srv->flags & ONOFF_SERVICE_HAS_ERROR) != 0;
}

/**
 * @brief Clear errors on an on-off service and reset it to its off
 * state.
 *
 * A service can only be reset when it is in an error state as
 * indicated by onoff_service_has_error().
 *
 * The return value indicates the success or failure of an attempt to
 * initiate an operation to reset the resource.  If initiation of the
 * operation succeeds the result of the reset operation itself is
 * provided through the configured client notification method,
 * possibly before this call returns.  Multiple clients may request a
 * reset; all are notified when it is complete.
 *
 * Note that the call to this function may succeed in a case where the
 * actual reset fails.  Always check the operation completion result.
 *
 * This function is blocking if the reset transition is blocking,
 * unless client notification specifies no-wait.
 *
 * @note Due to the conditions on state transition all incomplete
 * asynchronous operations will have been informed of the error when
 * it occurred.  There need be no concern about dangling requests left
 * after a reset completes.
 *
 * @param srv the service to be reset.
 *
 * @param cli pointer to client state, including instructions on how
 * to notify the client when reset completes.  Behavior is undefined
 * if cli references an object associated with an incomplete service
 * operation.
 *
 * @retval 0 on success
 * @retval -ENOTSUP if reset is not supported
 * @retval -EINVAL if the parameters are invalid, or if the service
 * @retval -EALREADY if the service does not have a recorded error
 */
int onoff_service_reset(struct onoff_service *srv,
			struct onoff_client *cli);

/**
 * @brief Attempt to cancel an in-progress client operation.
 *
 * It may be that a client has initiated an operation but needs to
 * shut down before the operation has completed.  For example, when a
 * request was made and the need is no longer present.
 *
 * There is limited support for cancelling an in-progress operation:
 * * If a start or reset is in progress, all but one clients
 *   requesting the start can cancel their request.
 * * If a stop is in progress, all clients requesting a restart can
 *   cancel their request;
 * * A client requesting a release cannot cancel the release.
 *
 * Be aware that any transition that was initiated on behalf of the
 * client will continue to progress to completion.  The restricted
 * support for cancellation ensures that for any in-progress
 * transition there will always be at least one client that will be
 * notified when the operation completes.
 *
 * If the cancellation fails the service retains control of the client
 * object, and the client must wait for operation completion.
 *
 * @param srv the service for which an operation is to be cancelled.
 *
 * @param cli a pointer to the same client state that was provided
 * when the operation to be cancelled was issued.  If the cancellation
 * is successful the client will be notified of operation completion
 * with a result of `-ECANCELED`.
 *
 * @retval 0 if the cancellation was completed before the client could
 * be notified.  The client will be notified through cli with an
 * operation completion of `-ECANCELED`.
 * @retval -EINVAL if the parameters are invalid.
 * @retval -EWOULDBLOCK if cancellation was rejected because the
 * client is the only waiter for an in-progress transition.  The
 * service retains control of the client structure.
 * @retval -EALREADY if cli was not a record of an uncompleted
 * notification at the time the cancellation was processed.  This
 * likely indicates that the operation and client notification had
 * already completed.
 */
int onoff_cancel(struct onoff_service *srv,
		 struct onoff_client *cli);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_SYS_ONOFF_H_ */
