#ifndef __EM_ESS_MANAGER_H
#define __EM_ESS_MANAGER_H

#include "em_common.h"

#define EM_ESS_TYPE_MAKE_TOKEN    0x0001
#define EM_ESS_TYPE_DELETE_TOKEN  0x0002
#define EM_ESS_TYPE_RECOVERY_DATA 0x0003

typedef struct em_ess_req_msg {
	uint8_t data[EM_LEN_MESSAGE];
	int len;
} em_ess_req_msg;

typedef struct em_ess_erm {
	uint8_t data[EM_LEN_MESSAGE];
	uint8_t data_b64[EM_LEN_MESSAGE];
	uint8_t str_len[EM_LEN_ESS_STR];
	uint8_t str_b64_len[EM_LEN_ESS_STR];
	int len;
} em_ess_erm;

typedef struct em_ess_ss_data {
	uint8_t iv[EM_LEN_SESSION_IV];
	uint8_t key[EM_LEN_SESSION_KEY];
} em_ess_ss_data;

typedef struct em_ess_unenc_esk {
	uint8_t wb_iv[EM_LEN_SESSION_IV];
	uint8_t wb_enc_ss_data[EM_LEN_WB_SS_IV_KEY];
	int wb_enc_ss_data_len;
} em_ess_unenc_esk;

typedef struct em_ess_esk {
	uint8_t data[EM_LEN_ESK];
	uint8_t data_b64[EM_LEN_ESK_B64];
	uint8_t str_len[EM_LEN_ESS_STR];
	uint8_t str_b64_len[EM_LEN_ESS_STR];
	int len;
} em_ess_esk;

typedef struct em_ess_hash {
	uint8_t ori[EM_LEN_ESK + EM_LEN_ERM];
	int ori_len;
	uint8_t data[EM_LEN_SHA256];
	uint8_t data_b64[EM_LEN_NONCE_B64];
	int len;
} em_ess_hash;

typedef struct em_ess_rx_ss_iv {
	uint8_t data[EM_LEN_SESSION_IV];
	int len;
} em_ess_rx_ss_iv;

typedef struct em_ess_etoken {
	uint8_t data[EM_LEN_TOKEN];
	int len;
} em_ess_etoken;

typedef struct em_ess_ctx {
	uint8_t protocol_version[EM_LEN_ESS_VERSION];
	uint8_t token_id[EM_LEN_TOKEN_ID + 1];
	uint8_t nonce_b64[EM_LEN_NONCE_B64];
	uint8_t iin_b64[EM_LEN_IIN_B64];
	em_ess_req_msg req_msg;
	em_ess_erm erm;
	em_ess_ss_data ss_data;
	em_ess_unenc_esk unenc_esk;
	em_ess_esk esk;
	em_ess_hash hash;
	em_ess_rx_ss_iv rx_ss_iv;
	em_ess_etoken etoken;
} em_ess_ctx;

void em_ess_update_req_msg(uint8_t *msg, uint32_t *msg_index, const uint8_t *input, const uint32_t input_size,
			   const uint8_t *delem, const uint32_t max_size, const uint32_t input_max_size);
int em_ess_make_token_request(em_context *ctx);
int em_ess_make_delete_request(em_context *ctx);
int em_ess_make_recovery_request(em_context *ctx);
int em_ess_install_token_v1(em_context *ctx);
int em_ess_recovery_esi_v1(em_context *ctx);
int em_ess_delete_token_offline(em_context *ctx);
int em_ess_get_info(em_context *ctx);

#endif
