/*
 * 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)

/** @internal */
#define ONOFF_FLAG_ONOFF BIT(1)
/** @internal */
#define ONOFF_FLAG_TRANSITION BIT(2)

/**
 * @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,			       \
}

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

/**
 * @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 {
	/** @internal
	 *
	 * Links the client into the set of waiting service users.
	 * Applications must ensure this field is zero-initialized
	 * before use.
	 */
	sys_snode_t node;

	/** @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 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 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;

	/** @brief 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_ */
