/* SPDX-FileCopyrightText: 2024 Google LLC */
/* SPDX-License-Identifier: Apache-2.0 */

#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "pebbleos/firmware_metadata.h"
#include "util/attributes.h"
#include "util/build_id.h"

extern const FirmwareMetadata TINTIN_METADATA;

//! Copies the version metadata of the running firmware in the provided struct.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_running_fw_metadata(FirmwareMetadata *out_metadata);

//! Copies the version metadata of the recovery firmware in the provided struct.
//! If there is no valid metadata available, the struct will be wiped to be all zeroes.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_recovery_fw_metadata(FirmwareMetadata *out_metadata);

//! Copies the version metadata of the update firmware located in
//! FLASH_REGION_FIRMWARE_DEST_BEGIN into the provided struct.
//! If there is no valid metadata available, the struct will be wiped to be all zeroes.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_update_fw_metadata(FirmwareMetadata *out_metadata);

//! Read recovery version_short from flash and copy to dest; copy at most
//! dest_len_bytes - 1 before being null-terminated via strncpy()
//!
//! @param dest: char[dest_len_bytes]
//! @returns true on success, false otherwise
bool version_copy_recovery_fw_version(char* dest, const int dest_len_bytes);

//! Checks to see if a valid PRF is installed with a correct checksum.
//! @return true if a PRF is installed, false otherwise.
bool version_is_prf_installed(void);

//! @return Pointer to the GNU build id data. This is a hash of the firmware
//! that is generated by the linker and uniquely identifies the binary.
//! @param[out] out_len The length of the build id in bytes.
const uint8_t * version_get_build_id(size_t *out_len);

//! Copies a hex C-string of the build id into the supplied buffer.
//! Get the build id from an elf, using `arm-none-eabi-readelf -n tintin_fw.elf`
//! @param[out] buffer The buffer into which the string should be copied.
//! @param max_length The length of buffer.
void version_copy_current_build_id_hex_string(char *buffer, size_t buffer_bytes_left);

//! Like version_copy_current_build_id_hex_string, but is copied from the specified Elf section.
void version_copy_build_id_hex_string(char *buffer, size_t buffer_bytes_left,
                                      const ElfExternalNote *build_id);

//! Returns the major, minor, and the rest in string form. The return value of patch_ptr is
//! read-only
void version_get_major_minor_patch(unsigned int *major, unsigned int *minor,
                                   char const **patch_ptr);
