/**
 * \file gatekeeper_common.h
**/
#ifndef GATEKEEPER_COMMON_H
#define GATEKEEPER_COMMON_H

#include "pw_handle.h"
#include "communication.h"
#include "hardware/hw_auth_token.h"
#include <stdint.h>
#include <stdbool.h>

typedef struct __sized_buffer__ {
    uint32_t size;
    uint8_t *buffer;
} sized_buffer;

typedef struct __enroll_request__ {
    sized_buffer pwd_hndl;
    sized_buffer enr_pwd;
    sized_buffer pwd;
} enroll_request;

typedef struct {
    uint32_t uid;
    int32_t result;
    uint32_t retry_timeout;
    passw_handle_t handle;
} enroll_responce_t;

typedef struct __verify_request__ {
    sized_buffer pwd_hndl;
    sized_buffer pwd;
} verify_request;

typedef struct {
    uint64_t challenge;
    uint32_t uid;
    int32_t result;
    uint32_t retry_timeout;
    bool request_reenroll;
    hw_auth_token_t token;
    //passw_handle_t handle;
} verify_responce_t;

typedef struct {
    uint64_t timestamp;
    uint32_t counter;
    uint64_t user_id; /* secure id (not android id) */
} fail_record_t;

/**
 * check if sized_buffer object is empty(buffer or size null)
 * @param[in] sized_buffer buffer
 * @return true if buffer is empty, else false
 */
bool gk_is_empty(const sized_buffer *buffer);

/**
 * copy constructor of sized_buffer,
 * create sized buffer and copy data to it(after using must call gk_free_sized_buffer)
 * @param[in] uint8_t* data
 * @param[in] uint32_t len - len of data
 * @param[out] sized_buffer *out - sized_buffer to create
 * @return true if success, else false
 */
bool gk_cp_to_sized_buffer(const uint8_t *data, uint32_t len, sized_buffer *out);

/**
 * destructor of sized_buffer, free sized buffer
 * @param[out] sized_buffer *obj - sized_buffer to destruct
 * @return true if buffer is empty, else false
 */
void gk_free_sized_buffer(sized_buffer *obj);

/**
 * verify enrolled password and handle and create new password handle for new handle
 * @param[in] enroll_request* rq
 * @param[out] enroll_responce_t* rsp
 * @param[in] fail_record_t *failure_record
 * @return
 */
void gk_enroll(const enroll_request *rq, enroll_responce_t *rsp, fail_record_t *failure_record);

/**
 * verify password and handle and create auth token for verified password
 * @param[in] enroll_request* rq
 * @param[out] verify_responce_t* responce
 * @param[in] fail_record_t *failure_record
 * @return
 */
void gk_verify(const verify_request *rq, verify_responce_t *rsp, fail_record_t *failure_record);

/**
 * verify auth token
 * @param[in/out] void* cmd_data - poiter to verify_auth_token_cmd_t struct
 * @return
 */
void gk_ver_auth_token(void *cmd_data);

#endif /* GATEKEEPER_COMMON_H */
