/*
 * app_json.h
 */

#ifndef _TZ_ICCC_APP_JSON_H_
#define _TZ_ICCC_APP_JSON_H_

#include "app_getDeviceStatus.h"

#include "icccOperations_v4.h"

/* IMAGE_STATUS bit */
#define IMAGE_STATUS_NOT_DOWNLOADED             0x0
#define IMAGE_STATUS_MARKET_USER_OFFICIAL       0x2
//#define IMAGE_STATUS_FACTORY_UNKNOWN_OFFICIAL  0x8 // Not downloaded in STAR/CROWN

/* number of IMAGE_STATUS */
#define IMAGE_STATUS_MAX                        12   // IMAGE_STATUS1 ~ IMAGE_STATUS_BL

/* IMAGE_STATUS CHECK RETURN */
#define IMAGE_STATUS_RESULT_NORMAL              0x0
#define IMAGE_STATUS_RESULT_ABNORMAL            0x1

//2 chars for '0x' + 16 chars for deviceId + 1 char for '/0'
#define DEVICE_ID_SIZE 19

typedef struct {
    uint32_t comp_type;
    uint8_t* nonce;
    tz_iccc_rsakey_t* key;
    uint8_t* certs[MAX_CERTS];
    uint32_t certs_len[MAX_CERTS];
    uint8_t certs_num;
    uint8_t* resp_msg_buf;
    uint32_t resp_msg_buf_size;
    uint32_t* resp_msg_len;
} ta_iccc_status_app_req_t;

/* All strings must be validated to be \0 terminated */
typedef struct {
    uint32_t result_code;
    uint8_t* result_msg;
    uint32_t comp_type;
    uint8_t* nonce;
    uint8_t device_id[DEVICE_ID_SIZE];
    uint8_t cert_chain[MAX_CERTS][MAX_CERT_LENGTH];
    uint8_t certs_num;
} ta_iccc_status_app_payload_t;

typedef struct {
    uint32_t r; // recovery
    uint32_t b; // boot
    uint32_t l; // bootloader
    uint32_t s; // system
    uint32_t v; // vendor
    uint32_t p; // product(odm)
    uint32_t c; // cache
    uint32_t u; // userdata
    uint32_t h; // hidden
    uint32_t o; // omr
    uint32_t dtb; // dtb
    uint32_t dtbo; // dtbo
} ta_iccc_binaryStatus_t;

typedef struct {
    uint32_t wb; // warranty bit
    uint32_t tb; // trusted boot
    uint32_t abs; // all binary status
    uint32_t reason; // wb History
    ta_iccc_binaryStatus_t binaryStatus;
    uint32_t es; // em_status
    uint32_t et; // em_token
    uint32_t hs; // hdm_status
} ta_iccc_payload_DIR_t;

typedef struct {
    const uint32_t flag;
    uint32_t* flag_value;
} DIR_flags_t;

#define ICCC_STATUS_APP_SIGN_SIZE 256

uint32_t generate_header(uint8_t *buffer, uint32_t *buffer_len, uint32_t buffer_size);
uint32_t encode_base64_in_place(uint8_t *buffer, uint32_t *buffer_len, uint32_t buffer_size);
uint32_t append_char_to_json(uint8_t *buffer, uint32_t buffer_size, uint32_t *buffer_len, uint8_t c);
uint32_t prepare_DIR_values();
uint32_t generate_DIR_message(uint8_t *buffer, uint32_t buffer_size, uint32_t *buffer_len);
uint32_t prepare_payload(ta_iccc_status_app_req_t *request, uint32_t result_code, uint8_t *ta_status_msg, ta_iccc_status_app_payload_t *payload);
uint32_t generate_payload(uint8_t *buffer, uint32_t buffer_size, uint32_t *buffer_len, ta_iccc_status_app_payload_t *payload);
uint32_t generate_signature(uint8_t *message, uint32_t *message_len, tz_iccc_rsakey_t *rsa_key);

#endif // _TZ_ICCC_APP_JSON_H_
