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

#ifndef ZEPHYR_INCLUDE_SYS_ONOFF_H_
#define ZEPHYR_INCLUDE_SYS_ONOFF_H_

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

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup resource_mgmt_onoff_apis On-Off Service APIs
 * @ingroup kernel_apis
 * @{
 */

/**
 * @brief Flag indicating an error state.
 *
 * Error states are cleared using onoff_reset().
 */
#define ONOFF_FLAG_ERROR BIT(0)

/** @cond INTERNAL_HIDDEN */
#define ONOFF_FLAG_ONOFF BIT(1)
#define ONOFF_FLAG_TRANSITION BIT(2)
/** @endcond */

/**
 * @brief Mask used to isolate bits defining the service state.
 *
 * Mask a value with this then test for ONOFF_FLAG_ERROR to determine
 * whether the machine has an unfixed error, or compare against
 * ONOFF_STATE_ON, ONOFF_STATE_OFF, ONOFF_STATE_TO_ON,
 * ONOFF_STATE_TO_OFF, or ONOFF_STATE_RESETTING.
 */
#define ONOFF_STATE_MASK (ONOFF_FLAG_ERROR   \
			  | ONOFF_FLAG_ONOFF \
			  | ONOFF_FLAG_TRANSITION)

/**
 * @brief Value exposed by ONOFF_STATE_MASK when service is off.
 */
#define ONOFF_STATE_OFF 0U

/**
 * @brief Value exposed by ONOFF_STATE_MASK when service is on.
 */
#define ONOFF_STATE_ON ONOFF_FLAG_ONOFF

/**
 * @brief Value exposed by ONOFF_STATE_MASK when the service is in an
 * error state (and not in the process of resetting its state).
 */
#define ONOFF_STATE_ERROR ONOFF_FLAG_ERROR

/**
 * @brief Value exposed by ONOFF_STATE_MASK when service is
 * transitioning to on.
 */
#define ONOFF_STATE_TO_ON (ONOFF_FLAG_TRANSITION | ONOFF_STATE_ON)

/**
 * @brief Value exposed by ONOFF_STATE_MASK when service is
 * transitioning to off.
 */
#define ONOFF_STATE_TO_OFF (ONOFF_FLAG_TRANSITION | ONOFF_STATE_OFF)

/**
 * @brief Value exposed by ONOFF_STATE_MASK when service is in the
 * process of resetting.
 */
#define ONOFF_STATE_RESETTING (ONOFF_FLAG_TRANSITION | ONOFF_STATE_ERROR)

/* Forward declarations */
struct onoff_manager;
struct onoff_monitor;

/**
 * @brief Signature used to notify an on-off manager 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 mgr the manager 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_notify_fn)(struct onoff_manager *mgr,
				int res);

/**
 * @brief Signature used by service implementations to effect a
 * transition.
 *
 * Service definitions use two required function pointers of this type
 * to be notified that a transition is required, and a third optional
 * one to reset the service when it is in an error 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 (where supported) will be called only when
 * onoff_has_error() returns true.
 *
 * @note All transitions functions must be isr-ok.
 *
 * @param mgr the manager for which transition was requested.
 *
 * @param notify the function to be invoked when the transition has
 * completed.  If the transition is synchronous, notify shall be
 * invoked by the implementation before the transition function
 * returns.  Otherwise the implementation shall capture this parameter
 * and invoke it when the transition completes.
 */
typedef void (*onoff_transition_fn)(struct onoff_manager *mgr,
				    onoff_notify_fn notify);

/** @brief On-off service transition functions. */
struct onoff_transitions {
	/** Function to invoke to transition the service to on. */
	onoff_transition_fn start;

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

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

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

	/** List of monitors to be notified of state changes including
	 * errors and transition completion.
	 */
	sys_slist_t monitors;

	/** Transition functions. */
	const struct onoff_transitions *transitions;

	/** Mutex protection for other fields. */
	struct k_spinlock lock;

	/** The result of the last transition. */
	int last_res;

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

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

/** @brief Initializer for a onoff_transitions object.
 *
 * @param _start a function used to transition from off to on state.
 *
 * @param _stop a function used to transition from on to off state.
 *
 * @param _reset a function used to clear errors and force the service
 * to an off state. Can be null.
 */
#define ONOFF_TRANSITIONS_INITIALIZER(_start, _stop, _reset) { \
		.start = (_start),			       \
		.stop = (_stop),			       \
		.reset = (_reset),			       \
}

/** @cond INTERNAL_HIDDEN */
#define ONOFF_MANAGER_INITIALIZER(_transitions) { \
		.transitions = (_transitions),	  \
}
/** @endcond */

/**
 * @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 mgr the manager definition object to be initialized.
 *
 * @param transitions pointer to a structure providing transition
 * functions.  The referenced object must persist as long as the
 * manager can be referenced.
 *
 * @retval 0 on success
 * @retval -EINVAL if start, stop, or flags are invalid
 */
int onoff_manager_init(struct onoff_manager *mgr,
		       const struct onoff_transitions *transitions);

/* 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-ok and not sleep.
 *
 * @param mgr the manager for which the operation was initiated.  This may be
 * null if the on-off service uses synchronous transitions.
 *
 * @param cli the client structure passed to the function that
 * initiated the operation.
 *
 * @param state the state of the machine at the time of completion,
 * restricted by ONOFF_STATE_MASK.  ONOFF_FLAG_ERROR must be checked
 * independently of whether res is negative as a machine error may
 * indicate that all future operations except onoff_reset() will fail.
 *
 * @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.  If res
 * is negative ONOFF_FLAG_ERROR will be set in state, but if res is
 * non-negative ONOFF_FLAG_ERROR may still be set in state.
 */
typedef void (*onoff_client_callback)(struct onoff_manager *mgr,
				      struct onoff_client *cli,
				      uint32_t state,
				      int res);

/**
 * @brief State associated with a client of an on-off service.
 *
 * Objects of this type are allocated by a client, which is
 * responsible for zero-initializing the node field and invoking the
 * appropriate sys_notify init function to configure notification.
 *
 * Control of the object content transfers to the service provider
 * when a pointer to the object is passed to any on-off manager
 * function.  While the service provider controls the object the
 * client must not change any object fields.  Control reverts to the
 * client concurrent with release of the owned sys_notify structure,
 * or when indicated by an onoff_cancel() return value.
 *
 * After control has reverted to the client the notify field must be
 * reinitialized for the next operation.
 */
struct onoff_client {
	/** @cond INTERNAL_HIDDEN
	 *
	 * Links the client into the set of waiting service users.
	 * Applications must ensure this field is zero-initialized
	 * before use.
	 */
	sys_snode_t node;
	/** @endcond */

	/** @brief Notification configuration. */
	struct sys_notify notify;
};

/**
 * @brief Identify region of sys_notify flags available for
 * containing services.
 *
 * Bits of the flags field of the sys_notify structure contained
 * within the queued_operation structure at and above this position
 * may be used by extensions to the onoff_client structure.
 *
 * These bits are intended for use by containing service
 * implementations to record client-specific information and are
 * subject to other conditions of use specified on the sys_notify API.
 */
#define ONOFF_CLIENT_EXTENSION_POS SYS_NOTIFY_EXTENSION_POS

/**
 * @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_reset().
 *
 * This is an unlocked convenience function suitable for use only when
 * it is known that no other process might invoke an operation that
 * transitions the service between an error and non-error state.
 *
 * @return true if and only if the service has an uncleared error.
 */
static inline bool onoff_has_error(const struct onoff_manager *mgr)
{
	return (mgr->flags & ONOFF_FLAG_ERROR) != 0;
}

/**
 * @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.
 *
 * @param mgr the manager 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 the observed state of the machine at the time
 * the request was processed, if successful.
 * @retval -EIO if service has recorded an error.
 * @retval -EINVAL if the parameters are invalid.
 * @retval -EAGAIN if the reference count would overflow.
 */
int onoff_request(struct onoff_manager *mgr,
		  struct onoff_client *cli);

/**
 * @brief Release a reserved use of an on-off service.
 *
 * This synchronously releases the caller's previous request.  If the
 * last request is released the manager will initiate a transition to
 * off, which can be observed by registering an onoff_monitor.
 *
 * @note Behavior is undefined if this is not paired with a preceding
 * onoff_request() call that completed successfully.
 *
 * @param mgr the manager for which a request was successful.
 *
 * @retval non-negative the observed state (ONOFF_STATE_ON) of the
 * machine at the time of the release, if the release succeeds.
 * @retval -EIO if service has recorded an error.
 * @retval -ENOTSUP if the machine is not in a state that permits
 * release.
 */
int onoff_release(struct onoff_manager *mgr);

/**
 * @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.
 *
 * Cancelling is supported only for onoff_request() and onoff_reset()
 * operations, and is a synchronous operation.  Be aware that any
 * transition that was initiated on behalf of the client will continue
 * to progress to completion: it is only notification of transition
 * completion that may be eliminated.  If there are no active requests
 * when a transition to on completes the manager will initiate a
 * transition to off.
 *
 * Client notification does not occur for cancelled operations.
 *
 * @param mgr the manager 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.
 *
 * @retval non-negative the observed state of the machine at the time
 * of the cancellation, if the cancellation succeeds.  On successful
 * cancellation ownership of @c *cli reverts to the client.
 * @retval -EINVAL if the parameters are invalid.
 * @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_manager *mgr,
		 struct onoff_client *cli);

/**
 * @brief Helper function to safely cancel a request.
 *
 * Some applications may want to issue requests on an asynchronous
 * event (such as connection to a USB bus) and to release on a paired
 * event (such as loss of connection to a USB bus).  Applications
 * cannot precisely determine that an in-progress request is still
 * pending without using onoff_monitor and carefully avoiding race
 * conditions.
 *
 * This function is a helper that attempts to cancel the operation and
 * issues a release if cancellation fails because the request was
 * completed.  This synchronously ensures that ownership of the client
 * data reverts to the client so is available for a future request.
 *
 * @param mgr the manager for which an operation is to be cancelled.
 *
 * @param cli a pointer to the same client state that was provided
 * when onoff_request() was invoked.  Behavior is undefined if this is
 * a pointer to client data associated with an onoff_reset() request.
 *
 * @retval ONOFF_STATE_TO_ON if the cancellation occurred before the
 * transition completed.
 *
 * @retval ONOFF_STATE_ON if the cancellation occurred after the
 * transition completed.
 *
 * @retval -EINVAL if the parameters are invalid.
 *
 * @retval negative other errors produced by onoff_release().
 */
static inline int onoff_cancel_or_release(struct onoff_manager *mgr,
					  struct onoff_client *cli)
{
	int rv = onoff_cancel(mgr, cli);

	if (rv == -EALREADY) {
		rv = onoff_release(mgr);
	}
	return rv;
}

/**
 * @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_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.
 *
 * @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 mgr the manager 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 non-negative the observed state of the machine at the time
 * of the reset, if the reset succeeds.
 * @retval -ENOTSUP if reset is not supported by the service.
 * @retval -EINVAL if the parameters are invalid.
 * @retval -EALREADY if the service does not have a recorded error.
 */
int onoff_reset(struct onoff_manager *mgr,
		struct onoff_client *cli);

/**
 * @brief Signature used to notify a monitor of an onoff service of
 * errors or completion of a state transition.
 *
 * This is similar to onoff_client_callback but provides information
 * about all transitions, not just ones associated with a specific
 * client.  Monitor callbacks are invoked before any completion
 * notifications associated with the state change are made.
 *
 * These functions may be invoked from any context including
 * pre-kernel, ISR, or cooperative or pre-emptible threads.
 * Compatible functions must be isr-ok and not sleep.
 *
 * The callback is permitted to unregister itself from the manager,
 * but must not register or unregister any other monitors.
 *
 * @param mgr the manager for which a transition has completed.
 *
 * @param mon the monitor instance through which this notification
 * arrived.
 *
 * @param state the state of the machine at the time of completion,
 * restricted by ONOFF_STATE_MASK.  All valid states may be observed.
 *
 * @param res the result of the operation.  Expected values are
 * service- and state-specific, but the value shall be non-negative if
 * the operation succeeded, and negative if the operation failed.
 */
typedef void (*onoff_monitor_callback)(struct onoff_manager *mgr,
				       struct onoff_monitor *mon,
				       uint32_t state,
				       int res);

/**
 * @brief Registration state for notifications of onoff service
 * transitions.
 *
 * Any given onoff_monitor structure can be associated with at most
 * one onoff_manager instance.
 */
struct onoff_monitor {
	/** Links the client into the set of waiting service users.
	 *
	 * This must be zero-initialized.
	 */
	sys_snode_t node;

	/** Callback to be invoked on state change.
	 *
	 * This must not be null.
	 */
	onoff_monitor_callback callback;
};

/**
 * @brief Add a monitor of state changes for a manager.
 *
 * @param mgr the manager for which a state changes are to be monitored.
 *
 * @param mon a linkable node providing a non-null callback to be
 * invoked on state changes.
 *
 * @return non-negative on successful addition, or a negative error
 * code.
 */
int onoff_monitor_register(struct onoff_manager *mgr,
			   struct onoff_monitor *mon);

/**
 * @brief Remove a monitor of state changes from a manager.
 *
 * @param mgr the manager for which a state changes are to be monitored.
 *
 * @param mon a linkable node providing the callback to be invoked on
 * state changes.
 *
 * @return non-negative on successful removal, or a negative error
 * code.
 */
int onoff_monitor_unregister(struct onoff_manager *mgr,
			     struct onoff_monitor *mon);

/**
 * @brief State used when a driver uses the on-off service API for synchronous
 * operations.
 *
 * This is useful when a subsystem API uses the on-off API to support
 * asynchronous operations but the transitions required by a
 * particular driver are isr-ok and not sleep.  It serves as a
 * substitute for #onoff_manager, with locking and persisted state
 * updates supported by onoff_sync_lock() and onoff_sync_finalize().
 */
struct onoff_sync_service {
	/** Mutex protection for other fields. */
	struct k_spinlock lock;

	/** Negative is error, non-negative is reference count. */
	int32_t count;
};

/**
 * @brief Lock a synchronous onoff service and provide its state.
 *
 * @note If an error state is returned it is the caller's responsibility to
 * decide whether to preserve it (finalize with the same error state) or clear
 * the error (finalize with a non-error result).
 *
 * @param srv pointer to the synchronous service state.
 *
 * @param keyp pointer to where the lock key should be stored
 *
 * @return negative if the service is in an error state, otherwise the
 * number of active requests at the time the lock was taken.  The lock
 * is held on return regardless of whether a negative state is
 * returned.
 */
int onoff_sync_lock(struct onoff_sync_service *srv,
		    k_spinlock_key_t *keyp);

/**
 * @brief Process the completion of a transition in a synchronous
 * service and release lock.
 *
 * This function updates the service state on the @p res and @p on parameters
 * then releases the lock.  If @p cli is not null it finalizes the client
 * notification using @p res.
 *
 * If the service was in an error state when locked, and @p res is non-negative
 * when finalized, the count is reset to zero before completing finalization.
 *
 * @param srv pointer to the synchronous service state
 *
 * @param key the key returned by the preceding invocation of onoff_sync_lock().
 *
 * @param cli pointer to the onoff client through which completion
 * information is returned.  If a null pointer is passed only the
 * state of the service is updated.  For compatibility with the
 * behavior of callbacks used with the manager API @p cli must be null
 * when @p on is false (the manager does not support callbacks when
 * turning off devices).
 *
 * @param res the result of the transition.  A negative value places the service
 * into an error state.  A non-negative value increments or decrements the
 * reference count as specified by @p on.
 *
 * @param on Only when @p res is non-negative, the service reference count will
 * be incremented if@p on is @c true, and decremented if @p on is @c false.
 *
 * @return negative if the service is left or put into an error state, otherwise
 * the number of active requests at the time the lock was released.
 */
int onoff_sync_finalize(struct onoff_sync_service *srv,
			 k_spinlock_key_t key,
			 struct onoff_client *cli,
			 int res,
			 bool on);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_SYS_ONOFF_H_ */
