/*   -*- coding: utf-8 -*-  */
/**********************************************************************
*
*  Module   : Explor
*  fichier  : ExplorAddFullText.c
*  Auteur   : Jacques DUCLOY
*  Date     : Decembre 2016 (reprend une parie de HfdSelect)
*
***********************************************************************/

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

#include "Hfd.h"
#include "Buffer.h"
#include "SxmlNode.h"
#include "TeiHandler.h"

static  Hfd     *hfd;
static  Hfd     *hfdPMC=NULL;
static  Hfd     *hfdISTEX=NULL;
static  int     flagKey;
static  int     flagHfd;
static  int     flagInsert;
static  int     flagNL;
static  int     flagInputBiblio;
static  char    *hfdName;
static  char    *input;
static  char    *separators;
static  Buffer  *buf;

/**
   Key mode
      Read the record which @a key was given as a parameter.
      convert in Sxml
      analyse publicationStmt

   Seek the notice which @a key is given as a parameter into @a hfd.
   Diplay it on standard output.

   If @a flagKey is true, @a key is also displayed on standard output.

   @param key the @a key of the notice to display
   @return 1 if the notice was retrieved.
           0 else
 */

char *computeHfdPath(SxmlNode *idnoNode)
{
  static Buffer *bPath=NULL;
  if (!bPath) bPath=NewBuffer();
  BufferStrcpy(bPath, getenv("EXPLOR_AREA"));
  BufferStrcat(bPath,"/Data/");
  BufferStrcat(bPath,SxmlGetAttribute(idnoNode, "wicri:stream"));
  BufferStrcat(bPath,"/Corpus/repository");
  return BufferString(bPath);

  return NULL;
}

SxmlNode *getHfdRecord(char *corpus)
{
  Hfd *curHfd;
  char *strDoc;
  SxmlNode *xmlDoc;
  HfdRecord *rec;
  SxmlNode *idnoNode;
  SxmlNode *corpusIdnoNode;

  corpusIdnoNode=NULL;
  idnoNode=SxmlGetFirstChildTagAtt(Tei_publicationStmt, "idno", "type", "wicri:explorRef");
  if(!idnoNode)return NULL;
  while (idnoNode)
    {
      if ((SxmlHasAttribute(idnoNode, "wicri:corpus", corpus))&&(SxmlHasAttribute(idnoNode, "wicri:step", "Corpus")))
	{
	  corpusIdnoNode=idnoNode;
	  break;
	}
      idnoNode=SxmlGetNextSiblingTagAtt(idnoNode, "idno", "type", "wicri:explorRef");
    }

  if (strcmp(corpus, "PMC")==0)
    {
      if (!hfdPMC) hfdPMC=HfdOpenReadKey(computeHfdPath(corpusIdnoNode));
      curHfd=hfdPMC;
    }
  if (strcmp(corpus, "ISTEX")==0)
    {
      if (!hfdISTEX) hfdISTEX=HfdOpenReadKey(computeHfdPath(corpusIdnoNode));
      curHfd=hfdISTEX;
    }
  rec=HfdRecordReadKey(curHfd,SxmlLeafText(corpusIdnoNode));
  strDoc=HfdRecordAfterKey(rec);
  xmlDoc=SxmlFromString(strDoc);
  return xmlDoc;
}

SxmlNode *addFullText(SxmlNode *recXml)
{
  TeiHandlerInit(recXml);
  if (TeiHandlerHasExplorSource("ISTEX")) 
    {
      SxmlNode *istexFT;
      SxmlNode *istexNode;
      istexFT=getHfdRecord("ISTEX");
      if ((istexNode=SxmlGetFirstChildByTagName(recXml, "istex")))SxmlFree(istexNode);
      SxmlAppendChild (recXml,istexFT);
    }
  else if (TeiHandlerHasExplorSource("PMC"))
    {
      SxmlNode *pmcFT;
      SxmlNode *pmcNodeTarget;
      SxmlNode *pmcNodeRepo;
      SxmlNode *pmcPart;
      pmcFT=getHfdRecord("PMC");
      if ((pmcNodeTarget=SxmlGetFirstChildByTagName(recXml, "pmc")))SxmlFree(pmcNodeTarget);
      pmcNodeRepo=SxmlGetFirstChildByTagName(pmcFT, "pmc");
      pmcPart=SxmlRemoveChild(pmcNodeRepo);
      SxmlFree(pmcFT);
      SxmlAppendChild (recXml,pmcPart);	 
    }
  return recXml;
}

int traitKey(char *key)
{
  HfdRecord *rec;
  char      *str;
  SxmlNode *recXml;

  if((rec=HfdRecordReadKey(hfd,key)))
    {
      str=HfdRecordAfterKey(rec);
      if (flagKey)printf("%s\t",key);
      recXml=SxmlFromString(str);
      addFullText(recXml);
      SxmlPrint(recXml);
      if (!flagNL)putchar('\n');
      SxmlFree(recXml);
      return 1;
    }
  return 0;
}

/**
   Display the notices from the key list in @a input.

   Do it without carriage return.
 */
void traitList()
{
  char *key;
  if ((key=strtok(input,separators)))
    {
      traitKey(key);
      while ((key=strtok(NULL,separators)))
	{
	  traitKey(key);
	}
    }
}


void traitInsert()
{
  char *posTab;
  if((posTab=strchr(input,'\t')))
    {
      posTab[0]='\0';
      if (traitKey(input))
	{
	  posTab[0]='\t';
	  puts(posTab);
	}
      else
	{
	  posTab[0]='\t';
	}
    }
  else
    {
      if(traitKey(input))putchar('\n');
    }
}

    int getopt();
    extern char *optarg;

void usage()
{
  perror ("usage: HfdSelect -s -h hfdName [-Kn] [-k key] [-l list]\n");
  exit(1);
}

int main(int argc, char **argv)
{

  int cod_arg;
  int flagInput;
  Buffer *bufHfdName;

  separators=" ,./;:\t\n";

  flagKey=0;
  flagHfd=0;
  flagInput=1;
  flagInputBiblio=0;
  flagInsert=0;
  flagNL=0;

  while ((cod_arg = getopt(argc,argv,"bk:h:il:Kns"))!=EOF)
    {switch(cod_arg) 
      {
      case 'b':
	flagInputBiblio=1;
	break;
      case 'i':
	flagInsert=1;
	break;

      case 'k' : 
	if(!flagHfd) usage();
	traitKey(optarg);
	break;

      case 'h' :
	hfdName=optarg;
	bufHfdName=BufferFromString(hfdName);
	while((BufferTailCmp(bufHfdName,"/")==0)
	      ||(BufferTailCmp(bufHfdName," ")==0))
	  BufferTailCut(bufHfdName,1);
	if (BufferTailCmp(bufHfdName,".hfd")==0)
	  BufferTailCut(bufHfdName,4);
	if((hfd=HfdOpenReadKey(BufferString(bufHfdName))))
	  {
	    flagHfd=1;
	    break;
	  }
	else
	  {
	    perror("HFD not founded\n");
	    usage();
	  }

      case 'K' :
	flagKey=1;
	break;

      case 'l' :
	if(!flagHfd) usage();
	input=optarg;
	traitList();
	break;

      case 'n':
	flagInput=0;
	break;

      default: usage();
	break;
      }};
  if (flagInputBiblio==1)
    {
      SxmlNode *inputDocument;
      while ((inputDocument=SxmlInputGetDocumentElement()))
	{
	  addFullText(inputDocument);
	  SxmlPrint(SxmlInputRecord);
	}
      exit (EXIT_SUCCESS);
    }
  if (flagInput==1)
    {
      buf=BufferCreate(132,132);
      if (flagInsert)flagNL=1;
      while ((input = BufferGets(buf)))
	{
	  if (flagInsert)traitInsert();
	  else traitList();
	}
      exit (EXIT_SUCCESS);
    }
  exit (EXIT_SUCCESS);
}
