#ifndef __SSL_FILE_H__
#define __SSL_FILE_H__

#include "ssl_file_list.h"

#define FILE_TYPE_SHAREABLE       0
#define FILE_TYPE_NON_SHAREABLE   1

#define FILE_TYPE_WORKING_EF   (0)
#define FILE_TYPE_INTERNAL_EF  (1)
#define FILE_TYPE_MF           (6)
#define FILE_TYPE_DF_ADF       (7)

#define FILE_TYPE_EF_STRUCT_NON_INFO     (0)
#define FILE_TYPE_EF_STRUCT_TRANSPARENT  (1)
#define FILE_TYPE_EF_STRUCT_LINEAR_FIXED (2)
#define FILE_TYPE_EF_STRUCT_CYCLIC       (5)

#define FILE_TYPE_EF_STRUCT_BERTLV       (57)


// 102.221 [table 11.5]
typedef enum{
	UNSHAREABLE = 0,
	SHAREABLE = 1,
} file_access;

//typedef enum{
	//EF = 0,
	//MF,
	//ADF = FILE_TYPE_DF_ADF,
	//DF = FILE_TYPE_DF_ADF,
//} file_type_t;

typedef enum{
	TRANSPARENT = FILE_TYPE_EF_STRUCT_TRANSPARENT,
	LINEAR = FILE_TYPE_EF_STRUCT_LINEAR_FIXED,
	CYCLIC = FILE_TYPE_EF_STRUCT_CYCLIC,
} ef_struct_t;


typedef struct file{
    union{
        fid_t fid;
        struct{
            uint8_t fid_lsb;
            uint8_t fid_msb;
        };
    };

    sfi_t sfi;

    union{
        uint8_t file_desc;
        struct{
            uint8_t ef_struct:3;
            uint8_t file_type:3;
            uint8_t shareable:1;
        };
    };

//extra
    const char *name;

//security
    union{
        fid_t arr_fid;
        struct{
            uint8_t arr_fid_lsb;
            uint8_t arr_fid_msb;
        };
    };
    uint8_t arr_record_id;

//LINEAR struct
    union{
        uint16_t record_len;
        struct{
            uint8_t record_len_lsb;
            uint8_t record_len_msb;
        };
    };
    uint8_t record_num;
    uint8_t record_pointer;

// Binary struct
    union{
        uint16_t file_len;
        struct{
            uint8_t file_len_lsb;
            uint8_t file_len_msb;
        };
    };
    uint8_t* data;


//hierarchy of usim file
	struct file* parent;
	file_list_t node;
	file_list_t child_ef;
	file_list_t child_df;

} __attribute__((packed))file_t, *file_ptr;

extern fid_t get_fid(uint8_t *bytes);
//extern file_ptr malloc_file_t(void);
extern file_ptr get_df_file_by_fid(file_ptr, fid_t);
extern file_ptr get_ef_file_by_fid(file_ptr, fid_t);
extern file_ptr get_file_by_fid(file_ptr, fid_t);
extern file_ptr get_file_by_sfi(file_ptr, sfi_t);
extern file_ptr get_file_by_path(file_ptr parent, uint8_t *path, size_t sz);
extern file_ptr create_DF(file_ptr parent, fid_t fid, uint8_t);
extern void dectroy_file_system(file_ptr);
extern file_ptr create_EF(file_ptr parent, fid_t fid, sfi_t, ef_struct_t ef_struct);
extern void dump_EF_file(file_ptr ef);
extern void dump_DF_file(file_ptr root);
extern void dump_file_system(file_ptr, int);

extern int save_data_of_file(file_ptr, uint8_t*, size_t);
extern int load_data_of_file(file_ptr, uint8_t*, size_t*);
extern int save_string_of_file(file_ptr file, char *value);

extern void free_file(file_ptr file);
#endif /*__SSL_FILE_H__*/

