/*   -*- coding: utf-8 -*-  */
/**********************************************************************
*
*  module   : Hfd
*  commande : HfdIndexBuildRec
*  fichier  : HfdIndexBuildRec.c
*  Auteur   : Jacques DUCLOY
*  Date     : Décembre 2014
*  Source   : IndexBuildRec
*
************************ Output ****************************
*
*  must be more understandable than Dilib Index one
*
* <index>
*   <key> 
*   <sort>  --- Optionnal ---  
*   <list>
*      <li>
*   <n>
*
************************ Input *********
*
*  pair        ( index key , hfd key )  - implicit
*  triplet   
*       ( index key , sorted key, hfd key )
*       ( index key , weight, hfd key )
*  separator   tab (implicit) or option - given by option -t
************************ Input *********
*
************************* Options ********
*    -t tabulation char
*    -s sortKey given by input (triplet)
*    -u sortKey via UTF-8 conversion
*
***********************************************************************/

#include "ctype.h"
#include "SxmlNode.h"
#include "Except.h"
#include "Buffer.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void perror();

void usage()
{
  fprintf (stderr ,"usage: HfdIndexBuildRec -suw [-t tabChar] \n");
  exit(EXIT_FAILURE);
}

static  SxmlNode *outputList;

static  Buffer *bufLine;
static  Buffer *bufKey;
static  Buffer *bufSortedKey;
static  Buffer *bufRecordKey;
char    *recordKey;

static int numberItems;

int sortedKeyOutput;
int sortedByUtf8;
int sortedByInput;
int weightMode;

static char *listTag;
static char *recordTag;
static char *keyTag;
static char *sortedKeyTag;
static char *itemTag;
static char *numberTag;

static char *formatNumber;

               /*             flags associes aux options */

static  char    tabChar;


void initList(char *key)
{
  BufferStrcpy(bufRecordKey, key);
  recordKey=BufferString(bufRecordKey);
  outputList=SxmlElementCreate(listTag);  /* will be free by purgeList */
  numberItems=0;
}


void purgeList()
{
  static char     strNumberItems[10];
  SxmlNode *outputRecord;
  SxmlNode *outputNumber;

  outputRecord=SxmlElementCreate(recordTag);
  SxmlAppendChild(outputRecord, SxmlLeafCreate (keyTag, recordKey));
  if (sortedKeyOutput)
    {
      SxmlAppendChild(outputRecord, SxmlLeafCreate (sortedKeyTag, BufferString(bufSortedKey)));
    }
  sprintf(strNumberItems,formatNumber,numberItems);
  outputNumber=SxmlLeafCreate(numberTag, strNumberItems);
  SxmlAppendChild(outputRecord, outputNumber);
  SxmlAppendChild(outputRecord, outputList);
  if (numberItems>0)
    {
      SxmlPrint(outputRecord);
      putchar('\n');
    }
  SxmlFree(outputRecord);
}

void elemList(char *item)
{
  SxmlNode *itemNode;
  itemNode=SxmlLeafCreate(itemTag, item);
  if (weightMode)
    {
      float w;
      sscanf(BufferString(bufSortedKey), "%f", &w);
      if (w<0.5) return;
      SxmlSetAttribute(itemNode, "w", BufferString(bufSortedKey));
    }
  SxmlAppendChild(outputList, itemNode);
  numberItems++;
}


    int getopt();
    extern char *optarg;

int main(argc,argv)
     int argc;
     char **argv;
{
  int cod_arg;
  char *line;

  tabChar='\t';

  bufKey=NewBuffer();
  bufLine=NewBuffer();
  bufRecordKey=NewBuffer();
  bufSortedKey=NewBuffer();

  recordKey=NULL;
  listTag="list";
  recordTag="index";
  keyTag="key";
  sortedKeyTag="sort";
  itemTag="li";
  numberTag="n";

  formatNumber="%d";

  sortedKeyOutput=0;
  sortedByUtf8=0;
  sortedByInput=0;
  weightMode=0;

  while (((cod_arg = getopt(argc,argv,"st:uw"))!=EOF))
    {
      switch(cod_arg) 
	{
	case 't':
	  tabChar=*optarg;
	  break;
	case 'u':
	  sortedKeyOutput=1;
	  sortedByUtf8=1;
	  break;
	case 's':
	  sortedKeyOutput=1;
	  sortedByInput=1;
	  break;
	case 'w':
	  weightMode=1;
	  break;
	default: 
	  usage();
	}
    }

  while ((line=BufferGets(bufLine))) 
    {
      char *posTabulation;
      char *newKey;
      char *item;

      posTabulation=strchr(line, tabChar);
      if (!posTabulation)
	{
	  ExceptSetError("HfdIndexBuildRec","IN","Line not fit (no key tab) :", line, "", 2);
	  exit (EXIT_FAILURE);
	}
      BufferStrncpy(bufKey, line, posTabulation-line);
      newKey=BufferString(bufKey);
      if(!recordKey) initList(newKey);
      else
	{
	  if (strcmp(recordKey, newKey)!=0)
	    {
	      purgeList();
	      initList(newKey);
	    }
	}
      if (sortedByInput||weightMode)
	{
	  char *posTab2;
	  posTab2=strchr(posTabulation+1, tabChar);
	  BufferStrncpy(bufSortedKey, posTabulation+1, posTab2-posTabulation-1);
	  item=posTab2+1;
	}
      else
	{
	  item=posTabulation+1;
	}
      elemList(item);
    }

  purgeList();
  return 0;
  exit (EXIT_SUCCESS);
}
