#include "dbupdate.h" 
#include "erroutines.h"

int tracing = 0;

void error_init(int argc, char ** argv) {
  er_path_t erlogstr;

  ER_init(argc, argv);

  erlogstr.fdes = stderr;
  erlogstr.asp  = 0;
  erlogstr.sev  = ER_SEV_W;
  erlogstr.mode = ER_M_SEVCHAR | ER_M_TEXTLONG;

  ER_setpath(& erlogstr);  

} /* error_init() */




void main(int argc, char **argv, char **envp){
  //schema.initialize();
  //init_and_set_options(argc, argv, envp);

  int count = 0;

  
  char *line;
  char *input_file_name = NULL;
  FILE * input_file;
  char *object = NULL;
  int object_count = 0;
  GSList *list_of_objects = NULL, *list_of_objects2 = NULL;   
  GSList *next = NULL;
  GHashTable* AUTO_NIC_hdl_hash;
  credentials_struct credentials;
  int reading_from_mail = 0;

  pid_t pid;
  char * mail_command_line, * ack_file_name;
  FILE * ack_file;
  int result = 0;
  
  extern char *optarg;
  extern int optind;

   
  object = NULL;
  credentials.password_list = NULL;
  credentials.from = NULL;
  int ch;
  char * to_address = NULL;

  AUTO_NIC_hdl_hash = g_hash_table_new(g_str_hash, g_str_equal);       
  error_init(argc, argv);
      
  line = (char *)malloc(1024);

  while ((ch = getopt(argc, argv, "Mtf:")) != -1){
          switch(ch) {
          case 'M':
                  reading_from_mail = 1;
                  break;
          case 'f':
                  input_file_name = strdup(optarg);
                  break;
          case 't': 
                  tracing = 1;
                  break;
          case '?':
          default:
                  printf("Unknown option\n");exit(1);
          }
  }

  /* if input_file_name is given in the command line, open and read it,
     otherwise, read from stdin */
  if(input_file_name == NULL){
    input_file = stdin;
  }else{
    if((input_file = fopen(input_file_name, "r")) == NULL){
       printf("Couldn't open the file %s: %s\n", input_file_name, strerror(errno));
       exit(1);  
    }
  }  

  while(fgets(line, 1024, input_file) != NULL){
    /* first, if it is a pasword, save it, but do not regard it as an attrib */ 
    if(strstr(line, "password:") == line){
      cout << "This is a password" << endl;
      credentials.password_list = g_slist_append(credentials.password_list, 
                                    g_strstrip(strdup(line + strlen("password:"))));
      continue;
    }
    /* if the length of the line read is 1, then this is an empty line */
    if(strlen(line) == 1){
       //cout << endl;
       if(object != NULL){
         //cout << "The object was" << endl << object << endl;
         list_of_objects = g_slist_append(list_of_objects, object);
         object = NULL;
       }
    }else{
      /* if the line contains only the EOL char */
      if(object == NULL && strlen(line) != 1){
        object = (char *)malloc(strlen(line));
        object = strdup(line);
      }
      else{
        object = (char *)realloc(object, strlen(object) + strlen(line));
        object = strcat(object, line);
      }
    }
      
  }

  /* now, if at the very and of the input file there wasn't an 
     empty line, we have to add the remaining object in the 'object'
     variable */
  if(object != NULL){
     //cout << "The object was" << endl << object << endl;
     list_of_objects = g_slist_append(list_of_objects, object);
     object = NULL;
  }

  /* initialize the parser */
  schema.initialize();

  pid = getpid();

  ack_file_name = (char *)malloc(strlen(ACK_FILE_PREFIX) + 128);
  sprintf(ack_file_name, "%s.%i", ACK_FILE_PREFIX, pid);

  if((ack_file = fopen(ack_file_name, "w")) == NULL){
    perror("Couldn't open ack file");
    exit(1);
  }




  if(tracing) {
     printf("TRACING: Will process the objects in the list\n");
  }
  next = list_of_objects;
  object_count = 0;
  for( next = list_of_objects; next != NULL ; next = g_slist_next(next) ){
    object_count++;
    /* if this is the first 'object' and we are getting an update from
       an e-mail message, then this is the mail header. */
    if(object_count == 1 ){
      if(reading_from_mail){
        printf("TRACING: Will process the mail header\n");
        process_mail_header(&credentials , (char *)next->data);
        to_address = find_to_address(credentials.from);
        /* Send a primitive ack */
        fprintf(ack_file, "To: ");
        fprintf(ack_file, to_address);
        fprintf(ack_file, "\nFrom: bit-bucket@ripe.net\nSubject: ack \nReply-To: bit-bucket@ripe.net\n\nAcknowledgement message from database software\n");
        if(credentials.from != NULL){
          fprintf(ack_file, "\n[%s]\n", credentials.from);
        }
        fclose(ack_file);
    
        continue;
      }else{
        fprintf(ack_file, "This is the ack file. The update is not a mail update\n");
        fclose(ack_file);
      }
    }              
                    
    if(tracing) {
      cout << "TRACING: Got an object from the list" << endl;
      cout << (char *)next->data << endl;
    }
     
    if(has_ref_to_AUTO_nic_hdl((char *)next->data)){/* defer the processing */
      if(tracing) {
        printf("TRACING: this object has a ref to an AUTO NIC hdl\n");
      }
      list_of_objects2 = g_slist_append(list_of_objects2, strdup((char *)next->data));
    }else{
      result = 0;
      result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name);
    }
  }

  if(tracing) {
    printf("TRACING: list_of_objects2 has %d entries\n", g_slist_length(list_of_objects2));
  }
  
  if(tracing) {
    printf("TRACING: will start to process the second list\n");
  }
  
  for( next = list_of_objects2; next != NULL ; next = g_slist_next(next) ){
    if(tracing) {
      printf("TRACING: Will process object: %s\n", (char *)next->data);
    }
    result = process_object((char *)next->data, credentials, AUTO_NIC_hdl_hash, ack_file_name);
  }


  if(reading_from_mail && to_address != NULL){
    mail_command_line = (char *)malloc(strlen(MAIL_CMD) + strlen(ack_file_name) + 128);

    sprintf(mail_command_line, "%s %s < %s", MAIL_CMD, to_address, ack_file_name);

    system(mail_command_line);
  }
  

  if(tracing) {
    printf("TRACING: END\n");
  }


}
