"""
/******************************************************************************

 @file product_util_13x0.py

 @brief This file contains a collection of utility functions used for
        specific SDK products

 Group: LPRF SW RND
 $Target Device: DEVICES $

 ******************************************************************************
 $License: BSD3 2019 $
 ******************************************************************************
 $Release Name: PACKAGE NAME $
 $Release Date: PACKAGE RELEASE DATE $
 *****************************************************************************/
"""

# -----------------------------------------------------------------------------
#                                   Constants
# -----------------------------------------------------------------------------

# Embedded Constants
HEADER_ADDR_TIRTOS_ROM = 0x4F0

# OAD Header Formats
FIXED_IMG_HEADER_FORMAT = "<HHHH4sHBB"
DELTA_SEG_FORMAT = "<8sBBHHH"
FIXED_IMG_HEADER_FIELDS = "crc crcShadow ver len uid startAddr imgType state"
DELTA_SEG_FIELDS = "deltaImgID toadMetaVer toadVer oldImgCrc newImgLen oldImgLen"

# OAD Header Constants
FIXED_IMG_HEADER_LEN = 16

FIXED_IMG_HEADER_CRC_SHADOW_OFFSET = 2
FIXED_IMG_HEADER_LEN_OFFSET = 6
FIXED_IMG_HEADER_USERID_OFFSET = 8
FIXED_IMG_HEADER_STATE_OFFSET = 15

FIXED_IMG_HEADER_DEFAULT_CRC_SHADOW = bytearray([0xFF, 0xFF])
FIXED_IMG_HEADER_DEFAULT_USERID = bytearray("EEEE", "utf-8")
FIXED_IMG_HEADER_DEFAULT_STATE = bytearray([0xFF])

# Turbo OAD Header Constants
DELTA_SEG_LEN = 16
DELTA_SEG_OFFSET = 16

DELTA_SEG_DELTA_IMG_ID = "TURBOOAD"
DELTA_SEG_DELTA_META_VER = 1
DELTA_SEG_DELTA_TOAD_VER = 1

# NV flash configuration for TIRTOS_IN_ROM CC13X0
# CRC and delta encoding must exclude NV pages so runtime NV writes
# (after network join) do not cause oldImgCrc mismatch.
# Match the linker: ONE_PAGE_NV => FLASH_NV_BASE = 0x1E000 (page 30)
#                  TWO_PAGE_NV => FLASH_NV_BASE = 0x1D000 (pages 29-30)
FLASH_APP_BASE = 0x1000   # APP_START_ADDR: binary starts here in flash
FLASH_NV_BASE  = 0x1E000  # ONE_PAGE_NV; change to 0x1D000 for TWO_PAGE_NV

# -----------------------------------------------------------------------------
#                                   Functions
# -----------------------------------------------------------------------------


def find_header_offset(binary):
    """
    Reads the OAD image binary and finds the location of the OAD image header

    :param binary: A bytearray of the OAD .bin file
    :return: The address offset of the OAD image header
    """

    # Detect if TIRTOS_IN_ROM is enabled for the binary
    header = bytearray(binary[:FIXED_IMG_HEADER_LEN])

    # Auto-detecting header based on default values of the CRC shadow, user ID, and state fields
    crc_shadow = header[FIXED_IMG_HEADER_CRC_SHADOW_OFFSET:(FIXED_IMG_HEADER_CRC_SHADOW_OFFSET + 2)]
    user_id = header[FIXED_IMG_HEADER_USERID_OFFSET:(FIXED_IMG_HEADER_USERID_OFFSET + 4)]
    state = header[FIXED_IMG_HEADER_STATE_OFFSET:(FIXED_IMG_HEADER_STATE_OFFSET + 1)]

    if (crc_shadow == FIXED_IMG_HEADER_DEFAULT_CRC_SHADOW and
            user_id == FIXED_IMG_HEADER_DEFAULT_USERID and
            state == FIXED_IMG_HEADER_DEFAULT_STATE):
        return 0x0
    else:
        return HEADER_ADDR_TIRTOS_ROM
