#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "mibs.h"
#include "util.h"

struct mibs_t root;

void readmibs() {
  void _readchildren(FILE *mibs_file,struct mibs_t *parent);

  FILE *mibs_file;
  char line[MAX];

  memset(&root,0,sizeof(root));
  if ((mibs_file = fopen("mibs.txt","r")) == NULL)
    printerror("Could not find mibs.txt");
  _readchildren(mibs_file,&root);
  fclose(mibs_file);
}

struct mibs_t * _readline(FILE *mibs_file, struct mibs_t *father,
                          int depth, int *level)
{
  struct mibs_t *ret_mib;
  char line[MAX],str[MAX];

  if ((*level = fgetc(mibs_file)) == EOF) return(NULL);
  if (*level != depth) {
    ungetc(*level,mibs_file);
    return(NULL);
  }
  if ((ret_mib = (struct mibs_t *)malloc(sizeof(struct mibs_t))) == NULL)
    printerror("Not enough memory");
  memset(ret_mib,0,sizeof(struct mibs_t));
  ret_mib->parent = father;
  if (fgets(line,sizeof(line),mibs_file) == NULL)
    printerror("Error parsing mib.txt");
  sscanf(line,"%d %s %c",&ret_mib->value,str,&ret_mib->type);
  if ((ret_mib->name = (char *)malloc(strlen(str)+1)) == NULL)
    printerror("Not enough memory");
  strcpy(ret_mib->name,str);
  return(ret_mib);
}

void _readchildren(FILE *mibs_file,struct mibs_t *parent) {
  struct mibs_t * _readline(FILE *mibs_file, struct mibs_t *father,
                            int depth, int *level);

  struct mibs_t *current;
  int depth, code;

  if ((depth = fgetc(mibs_file)) == EOF) return;
  ungetc(depth,mibs_file);
  current = parent->left_child = _readline(mibs_file,parent,depth,&code);
  if (current != NULL)
    while (code >= depth) {
      current->right_sibling = _readline(mibs_file,parent,depth,&code);
      if (code > depth) _readchildren(mibs_file,current);
      else if (code == depth) current = current->right_sibling;
    }
}

char parse_mib(char *mib) {
  int num, head, tail;
  struct mibs_t *current;
  char ret;

  current = &root;
  for (head=0,tail=1;mib[tail] && (mib[tail]!='.');tail++);
  while (mib[head]) {
    current = current->left_child;
    num = isdigit(mib[head+1]) ? atoi(mib+head+1) : -1;
    while ((current != NULL) && (current->value != num) &&
           (strncmp(mib+head+1,current->name,tail-head-1)!=0))
      current = current->right_sibling;
    if (current == NULL) break;
    else {
      current->expand = true;
      ret = current->type;
    }
    for (head=tail++;mib[head] && mib[tail] && (mib[tail]!='.');tail++);
  }
  return(ret);
}

