/*
 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __TIZEN_SYSTEM_DIAGNOSTICS_H__
#define __TIZEN_SYSTEM_DIAGNOSTICS_H__

#include <stdio.h>
#include <tizen.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup CAPI_SYSTEM_DIAGNOSTICS_MODULE
 * @{
 */

/**
 * @brief Diagnostics context.
 * @since_tizen 6.0
 */
typedef void* diagnostics_ctx_h;

/**
 * @brief Diagnostics data.
 * @since_tizen 6.0
 */
typedef void* diagnostics_data_h;

/**
 * @brief Enumeration for error codes of Diagnostics.
 * @since_tizen 6.0
 */
typedef enum {
    DIAGNOSTICS_ERROR_NONE = TIZEN_ERROR_NONE,                           /**< Successful */
    DIAGNOSTICS_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
    DIAGNOSTICS_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR,                   /**< I/O error */
    DIAGNOSTICS_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,         /**< Out of memory */
    DIAGNOSTICS_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY,         /**< Device or resource busy */
    DIAGNOSTICS_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,                 /**< Time out */
    DIAGNOSTICS_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,         /**< Not supported */
    DIAGNOSTICS_ERROR_TRY_AGAIN = TIZEN_ERROR_TRY_AGAIN,                 /**< Try again */
    DIAGNOSTICS_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED  /**< Permission denied */
} diagnostics_error_e;

/**
 * @brief Notification callback fired when new bug report arrives.
 * @since_tizen 6.0
 * @remarks @a ctx should be released with diagnostics_destroy()
 *
 * @param[in] ctx Diagnostics context handle
 * @param[in] user_data The user data passed from the callback registration function
 */
typedef void(*diagnostics_notification_cb)(diagnostics_ctx_h ctx, void *user_data);

/**
 * @brief Sets the callback for bug report notification.
 * @since_tizen 6.0
 *
 * @param[in] callback A callback function to set
 * @param[in] user_data The user data to be passed to the callback function
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 * @retval #DIAGNOSTICS_ERROR_RESOURCE_BUSY Callback already registered
 * @retval #DIAGNOSTICS_ERROR_IO_ERROR Internal error occured
 */
int diagnostics_set_notification_cb(diagnostics_notification_cb callback, void *user_data);

/**
 * @brief Unsets the callback for bug report notification.
 * @since_tizen 6.0
 * 
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_IO_ERROR Internal error occured
 */
int diagnostics_unset_notification_cb(void);

/**
 * @platform
 * @brief Requests client to dump data.
 * @since_tizen 6.0
 * @privlevel platform
 * @privilege
 * @remarks @a data should be released with diagnostics_data_destroy().
 * This function is permitted only to an app signed by platform level certificates.
 *
 * @param[in] client_id An id of app or service to request
 * @param[in] params Array of parameters
 * @param[in] params_size Number of parameters
 * @param[out] data Dumpsys data handle
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_PERMISSION_DENIED Permission denied
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 * @retval #DIAGNOSTICS_ERROR_IO_ERROR Internal error occured
 * @retval #DIAGNOSTICS_ERROR_OUT_OF_MEMORY Not enough memory to create data handle
 */
int diagnostics_request_client_data(const char *client_id, const char **params, int params_size, diagnostics_data_h *data);

/**
 * @brief Reads diagnostics data.
 * @since_tizen 6.0
 * @remarks @a data should be released with diagnostics_data_destroy().
 *          This function is intended for use in loop until EOF is reached.
 *          EOF is when @a bytes_read == 0 and function returns #DIAGNOSTICS_ERROR_NONE.
 * @param[in] data Diagnostics data handle
 * @param[in,out] buf Buffer to store read data \n
 *                    Provided buffer must be large enough to contain @a count number of bytes
 * @param[in] count Number of bytes to read
 * @param[in] timeout_ms Timeout [ms] for reading requested number of bytes (timeout_ms <= 0 means to wait forever)
 * @param[out] bytes_read Real number of read bytes
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 * @retval #DIAGNOSTICS_ERROR_TIMED_OUT Timeout occured
 * @retval #DIAGNOSTICS_ERROR_TRY_AGAIN Try again
 * @retval #DIAGNOSTICS_ERROR_IO_ERROR Internal error occured while trying to read data, result is unspecified and *bytes_read is not updated
 */
int diagnostics_data_read(diagnostics_data_h data, void *buf, size_t count, int timeout_ms, size_t *bytes_read);

/**
 * @brief Frees diagnostics data.
 * @since_tizen 6.0
 *
 * @param[in] data Diagnostics data handle
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 */
int diagnostics_data_destroy(diagnostics_data_h data);

/**
 * @brief Gets diagnostics context provider's id.
 * @since_tizen 6.0
 * @remarks @a client_id should be released with free().
 *
 * @param[in] ctx Diagnostics context handle
 * @param[out] client_id An id of the context provider
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 */
int diagnostics_get_client_id(diagnostics_ctx_h ctx, char **client_id);

/**
 * @platform
 * @brief Gets report data.
 * @since_tizen 6.0
 * @privlevel platform
 * @privilege
 * @remarks @a data should be released with diagnostics_data_destroy().
 * This function is permitted only to an app signed by platform level certificates.
 *
 * @param[in] ctx Diagnostics context handle
 * @param[in] params Array of parameters \n
 *                   Refer to context provider's documentation for available parameters
 * @param[in] params_size Number of parameters
 * @param[out] data Diagnostics data handle
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_PERMISSION_DENIED Permission denied
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 * @retval #DIAGNOSTICS_ERROR_IO_ERROR Internal error occured
 * @retval #DIAGNOSTICS_ERROR_OUT_OF_MEMORY Not enough memory to create data handle
 */
int diagnostics_get_data(diagnostics_ctx_h ctx, const char **params, int params_size, diagnostics_data_h *data);

/**
 * @brief Frees diagnostics context.
 * @since_tizen 6.0
 *
 * @param[in] ctx Diagnostics context handle
 *
 * @return 0 on success, otherwise a negative error value
 * @retval #DIAGNOSTICS_ERROR_NONE Success
 * @retval #DIAGNOSTICS_ERROR_NOT_SUPPORTED Not supported
 * @retval #DIAGNOSTICS_ERROR_INVALID_PARAMETER Provided parameter is invalid
 */
int diagnostics_destroy(diagnostics_ctx_h ctx);

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* __TIZEN_SYSTEM_DIAGNOSTICS_H__ */
