/***************************************
  $Revision: 1.3 $

  UP subject line parsing 

  Status: NOT REVIEWED, TESTED

  Author(s):       Engin Gunduz

  ******************/ /******************
  Modification History:
        engin (19/03/2001) Created.
  ******************/ /******************
  Copyright (c) 2001,2002                         RIPE NCC
 
  All Rights Reserved
  
  Permission to use, copy, modify, and distribute this software and its
  documentation for any purpose and without fee is hereby granted,
  provided that the above copyright notice appear in all copies and that
  both that copyright notice and this permission notice appear in
  supporting documentation, and that the name of the author not be
  used in advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.
  
  THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 ***************************************/


#include "UP_subject.h"
#include "glib.h"


/*
   Classifies the given word. The word can be HELP, HOWTO or NEW
   up_classify_word may return UP_KEYWORD_HELP (for HELP & HOWTO), 
   UP_KEYWORD_NEW (for NEW) or UP_KEYWORD_UNRECOG (for all others).
   Comparisons are case insensitive. 
*/
int up_classify_word(const char * word){

  if(word == NULL){
    return UP_KEYWORD_UNRECOG;
  }
  
  if( strcasecmp(word, "HOWTO") == 0 || strcasecmp(word, "HELP") == 0){

    return UP_KEYWORD_HELP;

  }else if( strcasecmp(word, "NEW") == 0){

    return UP_KEYWORD_NEW;

  }else{
 
    return UP_KEYWORD_UNRECOG;

  }

}




/* UP_subject_process function gets the "Subject:" line of a 
   update message and processes it. It tries to see if the
   words in the subject line are keywords that are recognised ones.
   The recognised ones are: HELP, HOWTO and NEW. The possible 
   return values are UP_SUBJ_HELP_REQ, UP_SUBJ_NEW_ENFORCED,
   UP_SUBJ_UNRECOG and UP_SUBJ_ALL_UNRECOG.

     UP_SUBJ_HELP_REQ means only HELP keyword is existent in the subject line
     UP_SUBJ_NEW_ENFORCED means only NEW keyword is existent in the subject line
     UP_SUBJ_UNRECOG means some unrecognised words found in subj line as well as
               at least one recognised one.
     UP_SUBJ_ALL_UNRECOG means all words were unrecognised ones (or subject
                            line was empty or non-existent)
     UP_SUBJ_INVALID_COMB means an invalid combination in given in the subject line. 
   */
up_subject_struct UP_subject_process(const char *arg){

  up_subject_struct return_struct; 
  char ** temp; 
  int i;
  char * list_of_nonkeywords = NULL;
  char * subject_line = NULL;

  subject_line = strdup(arg);


  /* initialize the struct */
  return_struct.result = UP_SUBJ_INIT;

  list_of_nonkeywords = strdup("");

  /* convert \t, \r, \n chars to white spaces */
  for(i=0; i < (strlen(subject_line)) ; i++){

    if(   subject_line[i] == '\t' || subject_line[i] == '\n'
       || subject_line[i] == '\r' ){
      subject_line[i] = ' ';
    }
  }

  /* split the string into lines */
  temp = g_strsplit (subject_line, " ", 0);

  for(i=0; temp[i] != NULL; i++){
    if(strlen(temp[i]) > 0){

      switch(up_classify_word(temp[i])){
        case UP_KEYWORD_HELP:
          switch(return_struct.result){

            case UP_SUBJ_INIT: 
              return_struct.result = UP_SUBJ_HELP_REQ; break;
            case UP_SUBJ_HELP_REQ: break;
            case UP_SUBJ_NEW_ENFORCED: 
              return_struct.result = UP_SUBJ_UNRECOG; break;
            case UP_SUBJ_UNRECOG: break;
            case UP_SUBJ_ALL_UNRECOG:
              return_struct.result = UP_SUBJ_UNRECOG;  break;
            case UP_SUBJ_INVALID_COMB: break;
            default: ;
          }; break;
              

        case UP_KEYWORD_NEW:
          switch(return_struct.result){

            case UP_SUBJ_INIT: 
              return_struct.result = UP_SUBJ_NEW_ENFORCED; break;
            case UP_SUBJ_HELP_REQ:
              return_struct.result = UP_SUBJ_INVALID_COMB; break;
            case UP_SUBJ_NEW_ENFORCED: break;
            case UP_SUBJ_UNRECOG: break;
            case UP_SUBJ_ALL_UNRECOG:
              return_struct.result = UP_SUBJ_UNRECOG;  break;
            case UP_SUBJ_INVALID_COMB: break;
            default: ;
          }; break;

        case UP_KEYWORD_UNRECOG:

          if(strlen(list_of_nonkeywords) == 0){
            list_of_nonkeywords = (char *)realloc(list_of_nonkeywords,
                  strlen(temp[i]) + 1);
            list_of_nonkeywords = strcat(list_of_nonkeywords, temp[i]);
          }else{
             list_of_nonkeywords = (char *)realloc(list_of_nonkeywords, 
                  strlen(list_of_nonkeywords) + strlen(temp[i]) + 2);
             list_of_nonkeywords = strcat(list_of_nonkeywords, " ");
             list_of_nonkeywords = strcat(list_of_nonkeywords, temp[i]);
          };

          switch(return_struct.result){

            case UP_SUBJ_INIT:
              return_struct.result = UP_SUBJ_ALL_UNRECOG; break;
            case UP_SUBJ_HELP_REQ:
              return_struct.result = UP_SUBJ_UNRECOG; break;
            case UP_SUBJ_NEW_ENFORCED:
              return_struct.result = UP_SUBJ_UNRECOG; break;
            case UP_SUBJ_UNRECOG: break;
            case UP_SUBJ_ALL_UNRECOG: break;
            case UP_SUBJ_INVALID_COMB:
              return_struct.result = UP_SUBJ_UNRECOG; break;
            default: ;

          }; break;
        default: ;
      }
    }
  }

  if(return_struct.result == UP_SUBJ_INIT){/* There were no words in the subject */
    return_struct.result = UP_SUBJ_ALL_UNRECOG;
  }

  return_struct.word_list = list_of_nonkeywords;

  free(subject_line);

  return return_struct;
}
