/*
 * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include <esp_err.h>
#include <esp_rcp_firmware.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    ESP_RCP_OTA_STATE_READ_HEADER = 0, /* State of reading image header */
    ESP_RCP_OTA_STATE_DOWNLOAD_RCP_FW, /* State of writing RCP firmware */
    ESP_RCP_OTA_STATE_FINISHED,        /* State of finishing RCP firmwares writing */
    ESP_RCP_OTA_STATE_INVALID,         /* Invalid state */
} esp_rcp_ota_state_t;

/* RCP OTA handle */
typedef uint32_t esp_rcp_ota_handle_t;

/**
 * @brief Initialize a handle of RCP OTA
 *
 * @param[out] out_handle On success, returns a handle which should be used for subsequent esp_rcp_ota_receive()
 * and esp_rcp_ota_end() calls.
 *
 * @return ESP_OK on success.
 * @return error in case of failure.
 */
esp_err_t esp_rcp_ota_begin(esp_rcp_ota_handle_t *out_handle);

/**
 * @brief Get state of RCP OTA
 *
 * @param[in] handle Handle of RCP OTA
 *
 * @return state of RCP OTA
 */
esp_rcp_ota_state_t esp_rcp_ota_get_state(esp_rcp_ota_handle_t handle);

/**
 * @brief Get subfile size from the parsed RCP image header
 *
 * This function must be called after the RCP OTA handle finishes the state of ESP_RCP_OTA_STATE_READ_HEADER
 *
 * @param[in] handle  Handle of RCP OTA
 * @param[in] filetag Tag of the subfile
 *
 * @return size of the subfile in the RCP image
 */
uint32_t esp_rcp_ota_get_subfile_size(esp_rcp_ota_handle_t handle, esp_rcp_filetag_t filetag);

/**
 * @brief Receive RCP OTA data
 *
 * This function should be called multiple times as data is received during the OTA operation.
 * Data should be read sequentially from the image file generated by esp_rcp_update/create_ota_image.py.
 *
 * @param[in]  handle        Handle of RCP OTA
 * @param[in]  data          Data buffer received
 * @param[in]  size          Size of data buffer in bytes.
 * @param[out] received_size Received size from the data buffer.
 *
 * @return ESP_OK on success.
 * @return error in case of failure.
 */
esp_err_t esp_rcp_ota_receive(esp_rcp_ota_handle_t handle, const void *data, size_t size, size_t *received_size);

/**
 * @brief Finish RCP OTA update, validate and apply newly updated image.
 *
 * @note After calling esp_rcp_ota_end(), the handle is no longer valid and any memory associated with
 *       it is freed (regardless of result).
 *
 * @param[in] handle Handle of RCP OTA
 *
 * @return ESP_OK on success.
 * @return error in case of failure.
 */
esp_err_t esp_rcp_ota_end(esp_rcp_ota_handle_t handle);

/**
 * @brief Abort RCP OTA update, free the handle and memory associated with it.
 *
 * @param[in] handle Handle of RCP OTA
 *
 * @return ESP_OK on success.
 * @return error in case of failure.
 */
esp_err_t esp_rcp_ota_abort(esp_rcp_ota_handle_t handle);

#ifdef __cplusplus
}
#endif
