#ifndef __HAL_MINIFDS_H
#define __HAL_MINIFDS_H

#include "system.h"
#include "bsp_flash.h"

#define USE_16BIT_KEY 1
#define MAX_RECORD_LENGTH 0xff

#if USE_16BIT_KEY
#define key_t unsigned short
#define length_t uint8_t
#else 
#define length_t unsigned short
#define key_t uint8_t
#endif

/**@brief   The record metadata as stored in flash.
 * @warning Do not edit or reorder the fields in this structure.
 */
typedef struct
{ 
	key_t record_key; //!< The record key.
  uint8_t crc8;       // < The
	length_t length;    //!< The length of the record
} minfds_record_t;

/**@brief Functions provided by the API implementation. */
typedef struct
{
  /**@brief flash写函数，p_dst为目标地址，p_src为源地址，sizewords为要写入的字（32位数据）（不是字节）的长度，写入成功需要返回0，写入失败返回其他值*/
  flash_OPER_Result (*flash_write)(uint32_t *p_dst, uint32_t const *p_src, uint32_t sizewords);
  /**@brief page_addr为要擦除的扇区的首地址 擦除成功需要返回0，失败返回其他值*/
  flash_OPER_Result (*flash_page_erase)(uint32_t page_addr);
} const flish_api_t;

typedef struct
{
  uint32_t start_addr;
  uint32_t end_addr;
  unsigned short record_count;
  uint32_t free_capacity;
  uint32_t duty_capacity;
  flish_api_t api;
} minfds_t;

/**@brief   FDS return values.
 */
enum
{
  MINIFDS_SUCCESS = 0,           //!< Error. 
  MINIFDS_ERR_NOT_INITIALIZED,   //!< Error. The module has not been initialized.
  MINIFDS_ERR_NOT_FREE_CAPACITY, //!< Error. The 空间不足>
  MINIFDS_ERR_NOT_FIND_RECORD,   //!< Error. The 没有找到记录>
  MINIFDS_ERR_BUSY,              //!< Error. The 忙>
  MINIFDS_ERR_API_FAIL,          //!< Error. The 底层接口报错>
  MINIFDS_ERR_REPEAT_KEY,        //!< Error. The key值错误，不能使用0>
  MINIFDS_ERR_HARDWARE,					 //!< Error. The flash被外部程序改变了>
  MINIFDS_ERR_PARAMETER,				 //!< Error. The 参数错误>
	MINIFDS_ERR_REPEAT_LENGTH,
};

//----------------------------------------------------------------

/**@brief startaddr 和 endaddr 为扇区的首地址，
 */
#define DEFINE_MINIINF(name, startaddr, endaddr, fun_write, fun_erase) \
  minfds_t name = {.start_addr = startaddr,                            \
                   .end_addr = endaddr,                                \
                   .record_count = 0,                                  \
                   .free_capacity = endaddr - startaddr,               \
                   .api.flash_write = fun_write,                       \
                   .api.flash_page_erase = fun_erase};

char minfds_record_add(minfds_t *p_minifds, key_t key, uint8_t *data, length_t length);

char minfds_record_find(minfds_t *p_minifds, key_t key, uint8_t *data, length_t *length);
									 
char minfds_record_get_length(minfds_t *p_minifds, key_t key, length_t *length);
									 
char minfds_record_find_mem(minfds_t *p_minifds, uint8_t *mem, int mem_len,key_t * key);

char minfds_record_update(minfds_t *p_minifds, key_t key, uint8_t *data, length_t length);

char minfds_record_delete(minfds_t *p_minifds, key_t key);

char minfds_record_delete_all(minfds_t *p_minifds);

char minfds_init(minfds_t *p_minifds);

char minfds_format(minfds_t *p_minifds);

unsigned short minfds_record_count_get(minfds_t *p_minifds);
									 
char record_index(minfds_t *p_minifds,minfds_record_t *record,uint8_t * data,int index);
//----------------------------------------------------------------


char pm_add(minfds_t *p_minifds,const char * key,int key_len,uint8_t *data, const length_t length);

char pm_find(minfds_t *p_minifds,const char * key,int key_len, uint8_t *data,length_t *length);

char pm_get_length(minfds_t *p_minifds, const char * key,int key_len, length_t *length);

char pm_update(minfds_t *p_minifds, const char * key,int key_len, uint8_t *data, length_t length);

char pm_delete(minfds_t *p_minifds, const char * key,int key_len);

#endif
