#ifndef _OMCLIB_MIB_PARSE_
#define _OMCLIB_MIB_PARSE_

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>

#define INTEGER_ENUM_TYPE 0
#define INTEGER_RANGE_TYPE 1
#define OCTET_STRING_TYPE 2
#define UNKNOWN_TYPE 99
/************** struct ****************/
typedef struct _object_identifier_t
{
	char name[64];
	int oid;
	char pname[64];
	int file_index;
}_object_identifier_t;

typedef struct _node_t
{
	struct _node_t *left;
	struct _node_t *right;
	_object_identifier_t *data;
}_node_t;

typedef struct _tmp_node_link
{
	struct _node_t *head_node;
}_tmp_node_link;

//--------------------------------
typedef struct _replace_type_t
{
	char type_name[64];
	char replacing_type_desc[2048];
	int type;
	char start_range[64];
	char end_range[64];
}_replace_type_t;

typedef struct _replace_node_t
{
	struct _replace_node_t *next;
	_replace_type_t *data;
}_replace_node_t;

typedef struct _replace_node_link
{
	struct _replace_node_t *head;
	struct _replace_node_t *tail;
}_replace_node_link;
//---------------------------------
typedef struct _word_t
{
	char *word;
	unsigned long line_no;
}_word_t;

typedef struct _word_node_t
{
	struct _word_node_t *prev;
	struct _word_node_t *next;
	_word_t *data;
}_word_node_t;

typedef struct _word_node_link
{
	struct _word_node_t *head;
	struct _word_node_t *tail;
}_word_node_link;
/**************************************/
typedef struct _line_mark
{
	int line_no;
	char previous_char;
	char previous_word[128];
	int previous_word_pos;
	int current_line_word_count;
	char previous_line[1024];
	int previous_line_pos;
	int previous_blank_char_count;
	char double_quote_flag;
	char previous_quote_content[8192];
	int previous_quote_content_pos;
	
	char single_quote_flag;
	char bracket_count;
	char comment_flag;
	char brace_flag;
	char punctuate_flag;
}_line_mark;

#define OUTPUT 1
#define ASSIGN_SIGN "::="

#define PARSE_STATE_UNCERTAIN 0
#define PARSE_STATE_OBJECT_IDENTIFIER 1
#define PARSE_STATE_IMPORT 2
#define PARSE_STATE_MRCRO 3
#define PARSE_STATE_MODULE_IDENTITY 4
#define PARSE_STATE_INTEGER 5
#define PARSE_STATE_TEXTUAL_CONVENTION 6
#define PARSE_STATE_OBJECT_TYPE 7




//OBJECT IDENTIFIER parse state
#define PARSE_OBJECT_ID_START 0
#define PARSE_OBJECT_ID_PNAME 1
#define PARSE_OBJECT_ID_OID 2
#define PARSE_OBJECT_ID_FINISH 3

//IMPORTS parse state
#define PARSE_IMPORT_STATE_WORD 0
#define PARSE_IMPORT_STATE_COMMA 1
#define PARSE_IMPORT_STATE_FROM 2
#define PARSE_IMPORT_STATE_SEMICOLON 3

//MACRO parse state
#define PARSE_MACRO_STATE_BEGIN 0
#define PARSE_MACRO_STATE_END 1


//MODULE-IDENTITY parse state
#define PARSE_MODULE_IDENTITY_STATE_SIGN 0
#define PARSE_MODULE_IDENTITY_STATE_START 1
#define PARSE_MODULE_IDENTITY_STATE_PNAME 2
#define PARSE_MODULE_IDENTITY_STATE_OID 3
#define PARSE_MODULE_IDENTITY_STATE_FINISH 4

//INTEGER parse state
#define PARSE_INTEGER_STATE_START 0
#define PARSE_INTEGER_STATE_LABEL 1
#define PARSE_INTEGER_STATE_VALUE 2

//TEXTUAL-CONVENTION parse state
#define PARSE_TEXTUAL_STATE_SYNTAX 0
#define PARSE_TEXTUAL_STATE_CHECK 1
#define PARSE_TEXTUAL_STATE_INTEGER 2
#define PARSE_TEXTUAL_STATE_INTEGER_CHECK 3
#define PARSE_TEXTUAL_STATE_INTEGER_ENUM 4
#define PARSE_TEXTUAL_STATE_INTEGER_LABEL 5
#define PARSE_TEXTUAL_STATE_INTEGER_VALUE 6
#define PARSE_TEXTUAL_STATE_OCTET_STRING 7
#define PARSE_TEXTUAL_STATE_SIZE 8
#define PARSE_TEXTUAL_STATE_RANGE 9

//OBJECT-TYPE parse state
#define PARSE_OBJECT_TYPE_STATE_SYNTAX 0
#define PARSE_OBJECT_TYPE_STATE_CHECK 1
#define PARSE_OBJECT_TYPE_STATE_ACCESS 2
#define PARSE_OBJECT_TYPE_STATE_STATUS 3
#define PARSE_OBJECT_TYPE_STATE_DESC 4
#define PARSE_OBJECT_TYPE_STATE_OID 5

typedef struct _mib_file_info
{
	char filename[64];
	char file_begin_flag;
	char file_end_flag;
	
	char store_word[64][128];
	int store_word_count;
	char store_desc[4][8192];
	int store_desc_count;
}_mib_file_info;

typedef struct _mib_parse_mng
{
	int parse_state;
	int parse_block_state;
}_mib_parse_mng;

#define MAX_IMPORT_OBJ 64
typedef struct _import_obj
{
	char import_word[MAX_IMPORT_OBJ][64];
	char import_file[MAX_IMPORT_OBJ][64];
	int word_index;
	int file_index;
}_import_obj;

//------------------------------------------------
#define VALUETYPE_OTHER          0
#define VALUETYPE_OBJID          1
#define VALUETYPE_OCTETSTR       2
#define VALUETYPE_INTEGER        3
#define VALUETYPE_NETADDR        4
#define VALUETYPE_IPADDR         5
#define VALUETYPE_COUNTER        6
#define VALUETYPE_GAUGE          7
#define VALUETYPE_TIMETICKS      8
#define VALUETYPE_OPAQUE         9
#define VALUETYPE_NULL           10
#define VALUETYPE_COUNTER64      11
#define VALUETYPE_BITSTRING      12
#define VALUETYPE_NSAPADDRESS    13
#define VALUETYPE_UINTEGER       14
#define VALUETYPE_UNSIGNED32     15
#define VALUETYPE_INTEGER32      16
#define VALUETYPE_TRAPTYPE	    20
#define VALUETYPE_NOTIFTYPE      21
#define VALUETYPE_OBJGROUP	    22
#define VALUETYPE_NOTIFGROUP	    23
#define VALUETYPE_MODID	    	24
#define VALUETYPE_AGENTCAP       25
#define VALUETYPE_MODCOMP        26
#define VALUETYPE_OBJIDENTITY    27

#define ACCESS_READONLY    18
#define ACCESS_READWRITE   19
#define	ACCESS_WRITEONLY   20
#define ACCESS_NOACCESS    21
#define ACCESS_NOTIFY      67
#define ACCESS_CREATE      48

#define STATUS_MANDATORY   23
#define STATUS_OPTIONAL    24
#define STATUS_OBSOLETE    25
#define STATUS_DEPRECATED  39
#define STATUS_CURRENT     57

typedef struct _mib_object
{
	int type;
	int oid[64];
	int oidlen;
	char name[64];
	int access;
	int status;
	char initvalue[128];
	char minvalue[64];
	char maxvalue[64];
	char valuestring[2048];
	char desc[8192];
	int need_find_oid;
	int have_find_oid;
	int hookvalue;
}MIB_OBJECT;

typedef struct _object_node_t
{
	struct _object_node_t *next;
	MIB_OBJECT *data;
}_object_node_t;

typedef struct _object_node_link
{
	struct _object_node_t *head;
	struct _object_node_t *tail;
}_object_node_link;

char mib_directory[64];
/************** Public function ****************/
/* Set the mib directory */
int set_mib_directory(char *dir);

/* Load mib information from file */
/* flag=1: store the MIB OBJECT from this file, then can enum them later */
/* hookvalue: this value will store in every object, then can trace it between load files */
int load_mib_file(char *filename,int flag,int hookvalue);

/* MIB OBJECT will skip the prefix length of the OID */
void set_prefix_oid_length(int poidlen);

/* Enumerate the MIB OB one by one, when finished, return NULL */
void prepare_enum();
MIB_OBJECT* enum_object();

/* Free all resource */
void free_resource();

/*************** Private function *****************/
int parse_mib();
int add_object_node(_object_identifier_t *data);
void free_object_node();
_node_t* find_object_node(_node_t* parent,char *name);
void list_object_id();
void list_object(_node_t *node);
void lookup_object_oid(char *name,int *oid,int *oidlen);
void reverse_oids(int *oid,int *oidlen);
void print_object(MIB_OBJECT *pobject);

int add_replace_node(_replace_type_t *data);
void free_replace_node();

int add_mib_object_node(MIB_OBJECT *data);
void free_mib_object_node();

int add_word_node(_word_t *data);
void free_word_node();
char *get_next_word(_word_node_t *refer_node,int index);
char *get_prev_word(_word_node_t *refer_node,int index);

void parse_range(char *input,char *start,char *end);
int is_digit_string(char *input);

int find_syntax_from_textual(char *type_name,MIB_OBJECT *pobject);

void free_last_file_object_node();
void move_object_node(_node_t *node);
int add_move_node(_object_identifier_t *data);
void find_last_file_oid();
#endif

