/*   -*- coding: utf-8 -*-  */

/*
           InistPair2Tei.c

 */

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>
#include "TeiHandler.h"
#include "Except.h"


#include "Buffer.h"
#include "Utf8Converter.h"
#include "Explor.h"

SxmlNode *docInput;
SxmlNode *record;
SxmlNode *teiRoot;
SxmlNode *teiHeader;

SxmlNode *editionStmt;
SxmlNode *author;

SxmlNode *inistPart;
SxmlNode *inistIdxNode;
SxmlNode *serverIdxNode;
SxmlNode *InistPA;

SxPathResult *indexPathServer;
SxPathResult *indexPathInist;
SxPathResult *inistPathA47;
SxPathResult *inistPathA08;


static Buffer *bufName;
static Buffer *bufForename;

static Buffer *bufKey;
static Buffer *bufSort;

SxmlNode *serverNode;
SxmlNode *standardNode;

SxmlNode *fA01;
SxmlNode *fA03;
SxmlNode *fA08;
SxmlNode *fA09;
SxmlNode *fA11;
SxmlNode *fA12;
SxmlNode *fA14;
SxmlNode *fA15;
SxmlNode *fA18;
SxmlNode *fA21;
SxmlNode *fA21s1;
SxmlNode *fA64;
SxmlNode *fA47;
SxmlNode *fC03;
SxmlNode *fC01;

SxmlNode *title;

char *inistGetFieldLang(SxmlNode *field)
{
  char *langAtt;
  langAtt=SxmlGetAttribute(field,"l");
  if (!langAtt) return ("*NO*");
  if (strcmp (langAtt,"ENG")==0) return "en";
  if (strcmp (langAtt,"FRE")==0) return "fr";
  return langAtt;
}


char *iterSZ(SxmlNode *Z, int indic)
{
  char* val;
  SxmlNode *nextZ;
  int indic1;
  val =SxmlLeafText(Z);
  sscanf(val,"%d",&indic1);
  if (indic==indic1)return val;
  if((nextZ=SxmlGetNextSiblingByTagName(Z,"sZ"))) return iterSZ(nextZ, indic);
  else return NULL;
}


void iterA1415(SxmlNode *A1415, SxmlNode *autNode, int indic, char *tag1415)
{
  SxmlNode *sZ;
  SxmlNode *nextA14;
  SxmlNode *affiliation;
  SxmlNode *newA14;

  if ((sZ=SxmlGetFirstChildByTagName(A1415,"sZ")))
    {
      if(iterSZ(sZ,indic))
	{
	  SxmlAppendChild(autNode, affiliation=SxmlElementCreate("affiliation"));
	  SxmlAppendChild(affiliation,newA14=SxmlClone(A1415));
	  SxmlSetNodeName(newA14,strdup("inist:fA14"));
	}
      /* return; */
    }
  else
    {
      if (indic>1)return;
      SxmlAppendChild(autNode, affiliation=SxmlElementCreate("affiliation"));
      SxmlAppendChild(affiliation,newA14=SxmlClone(A1415));
      SxmlSetNodeName(newA14,strdup("inist:fA14"));
    }
  if((nextA14=SxmlGetNextSiblingByTagName(A1415,tag1415)))iterA1415(nextA14, autNode, indic, tag1415);
  return;
}

SxmlNode *pascalKeywordFr;

void iterKw(SxmlNode *fC03)
{
  char *lang;
  SxmlNode *nextFC03;
  char *term;
  SxmlNode *s0;
  lang=SxmlGetAttribute(fC03,"l");
  s0=SxmlGetFirstChildByTagName(fC03,"s0");
  if (s0 && lang && (SxmlIsLeaf(s0)) && (term=SxmlLeafText(s0)))
    {
      /*  if ((lang=SxmlGetAttribute(fC03,"l"))) */
      if (strcmp(lang,"FRE")==0)
	{
	  if(!pascalKeywordFr)
	    {
	      SxmlAppendChild(Tei_textClass, pascalKeywordFr=SxmlElementCreate("keywords"));
	      SxmlSetAttribute(pascalKeywordFr,"scheme","Pascal");
	      SxmlSetAttribute(pascalKeywordFr,"xml:lang","fr");
	    }
	  /*  SxmlAppendChild(pascalKeywordFr, SxmlLeafCreate("term", SxmlLeafText(SxmlGetFirstChildByTagName(fC03,"s0")))); */
	  SxmlAppendChild(pascalKeywordFr, SxmlLeafCreate("term", term));
	}
      else if (strcmp(lang,"ENG")==0)
	{
	  TeiKeywordsPutTerm("KwdEn", NULL, NULL, "en", term);
	}
    }
  if ((nextFC03=SxmlGetNextSiblingByTagName(fC03,"fC03"))) iterKw(nextFC03);
}

SxmlNode *computeAuthorName(SxmlNode *s1)
{
  char *par;
  char *name;
  SxmlNode *xName;
  name=SxmlLeafText(s1);
  if (!name)return NULL;
  if ((par=strchr(name,'(')))
    {
      BufferStrncpy(bufName, name, par-name-1);
      BufferStrcpy(bufForename, par+1);
      BufferTailCut(bufForename,1);
      xName=TeiAuthorNameFromFirstLastNamesStr(BufferString(bufForename), BufferString(bufName));
      /*
      BufferStrcpy(bufKey, Utf8NameToLower(BufferString(bufForename)));
      BufferStrcat(bufKey, " ");
      BufferStrcat(bufKey, Utf8NameToLower(BufferString(bufName)));
      xName= SxmlLeafCreate("name",BufferString(bufKey));
      BufferStrcpy(bufSort, Utf8NameToWikiSort(BufferString(bufName)));
      BufferStrcat(bufSort, ", ");
      BufferStrcat(bufSort, Utf8NameToWikiSort(BufferString(bufForename)));
      SxmlSetAttribute(xName, "sortKey", BufferString(bufSort));
      BufferStrcpy(bufSort, Utf8NameToWikiSort(BufferString(bufName)));
      BufferStrcat(bufSort, " ");
      BufferStrcat(bufSort, Utf8NameToInitial(BufferString(bufForename)));
      SxmlSetAttribute(xName, "uniqKey", BufferString(bufSort));
      */
    }
  else
    {
      /* SxmlAppendChild(author, SxmlLeafCreate("name",name)); */
      xName=TeiAuthorNameFromFirstLastNamesStr(NULL, name);
      /* xName=SxmlLeafCreate("name",name); */
    }
  return xName;
}

void setNoAffiliation (SxmlNode *author)
{
  SxmlNode *affiliation;
  SxmlNode *inistServerAF;
  inistServerAF=SxmlGetFirstChildByTagName(serverNode, "AF");
  SxmlAppendChild(author, affiliation=SxmlElementCreate("affiliation"));
  if (inistServerAF)
    {  
      if (SxmlIsLeaf(inistServerAF)) 
	{
	  SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noCountry","no FA14"));
	  return;
	}
    }
  SxmlAppendChild(affiliation, SxmlLeafCreate("wicri:noCountry","no AF"));
}

void iterAut(SxmlNode *A11)
{
  SxmlNode *nextA11;
  SxmlNode *s1;
  int indAut;
  char *i1;
  author=SxmlElementCreate("author");
  SxmlAppendChild(Tei_titleStmt,author);
  if ((s1=SxmlGetFirstChildByTagName(A11,"s1")))
    {
      SxmlNode *xName;
      xName=computeAuthorName(s1);
      SxmlAppendChild(author, xName);
      if (fA14)
	{
	  if((i1=SxmlGetAttribute(A11,"i1")))
	    {
	      sscanf(i1,"%d",&indAut);
	      iterA1415(fA14, author,indAut, "fA14");
	    }
	}
      else setNoAffiliation (author);
    }
  SxmlAppendChild(Tei_analytic, SxmlClone(author));
  if ((nextA11=SxmlGetNextSiblingByTagName(A11,"fA11"))) iterAut(nextA11);
}

void iterA12(SxmlNode *A12)
{
  SxmlNode *nextA12;
  SxmlNode *s1;
  int indAut;
  char *i1;
  if (fA11)return;   /* must be improved */
  author=SxmlElementCreate("author");
  SxmlAppendChild(Tei_titleStmt,author);
  if ((s1=SxmlGetFirstChildByTagName(A12,"s1")))
    {
      SxmlNode *xName;
      xName=computeAuthorName(s1);
      SxmlAppendChild(author, xName);
      if ((fA15=SxmlGetFirstChildByTagName(InistPA,"fA15")))
	{
	  if((i1=SxmlGetAttribute(A12,"i1")))
	    {
	      sscanf(i1,"%d",&indAut);
	      iterA1415(fA15,author,indAut, "fA15");
	    }
	}
      else
	{
	  if ((fA18=SxmlGetFirstChildByTagName(InistPA,"fA18")))
	    {
	      if((i1=SxmlGetAttribute(A12,"i1")))
		{
		  sscanf(i1,"%d",&indAut);
		  iterA1415(fA18,author,indAut, "fA18");
		}
	    }
	  else setNoAffiliation (author);
	}
    }
  if ((nextA12=SxmlGetNextSiblingByTagName(A12,"fA12"))) iterA12(nextA12);
}

SxmlNode *inistCreateRecord()
{
  SxmlNode *lNode;
  SxmlNode *kNode;
  if(!SxmlNodeHasName(docInput,"idx"))
    {
      ExceptSetError("InistPair2Tei","IN", "Input not idx ", "", "", 1);
      return NULL;
    }

  lNode=SxmlGetFirstChildByTagName(docInput,"l");
  kNode=SxmlGetFirstChildByTagName(docInput,"k");	  

  record=SxmlElementCreate("record");
  SxmlAppendChild(record, teiRoot=TeiHandlerNew());
  SxmlSetAttribute(teiRoot, "xmlns:inist", "http://www.inist.fr");
  TeiAppendIdno("wicri:source","INIST");
  SxmlAppendChild(record, inistPart=SxmlElementCreate("inist"));

  if ((inistIdxNode=SxPathFirstResultNode(indexPathInist,lNode)))
    {
      SxmlAppendChild(inistPart, standardNode=SxmlClone(inistIdxNode));
      SxmlSetNodeName(standardNode,strdup("standard"));
    }
  else
    {
      ExceptSetError("InistPair2Tei","IN", "no inist in input ", "", "", 1);
      return NULL;
    }
  if ((serverIdxNode=SxPathFirstResultNode(indexPathServer,lNode)))
    {
      SxmlAppendChild(inistPart, serverNode=SxmlClone(serverIdxNode));
    }
  else
    {
      ExceptSetError("InistPair2Tei","IN", "No server in input ", "", "", 1);
      return NULL;
    }
  return record;
}

void computeId()
{
  SxmlNode *NO;   
  SxmlNode *idno;
  if ((NO=SxmlGetFirstChildByTagName(serverNode, "NO")))
    {
      char *strNO;
      SxmlAppendChild(Tei_publicationStmt, idno=SxmlLeafCreate("idno",strNO=SxmlLeafText(NO)));
      SxmlSetAttribute(idno, "type", "stanalyst");
      if(fA47)
	{
	  static Buffer *bufIdno=NULL;
	  if (!bufIdno)bufIdno=NewBuffer();
	  if (strNO[0]=='F')BufferStrcpy(bufIdno,"Francis:");
	  else BufferStrcpy(bufIdno,"Pascal:");
	  BufferStrcat (bufIdno,SxmlLeafText(fA47));
	  TeiAppendIdno("RBID", BufferString(bufIdno));
	}
    }
}

int main (int argc, char **argv) {
  int  cOption;
  char *pathParamFile;

  pathParamFile=NULL;
   while((cOption=getopt(argc,argv,"s:t:"))!=EOF)
     {switch (cOption)
	 {
	 case 's':
	   ExplorStreamCode=optarg;
	   break;
	 case 't':
	   pathParamFile=optarg;
	   break;
	 }
     }

   if (pathParamFile) ExplorParamInit(pathParamFile);  

  bufName=BufferCreate(10,10);
  bufSort=BufferCreate(10,10);
  bufForename=BufferCreate(10,10);
  bufKey=BufferCreate(10,10);
  
  indexPathServer=SxPathFirstCompile("e/server");
  indexPathInist=SxPathFirstCompile("e/inist");
  inistPathA47=SxPathFirstCompile("pA/fA47/s0");
  inistPathA08=SxPathFirstCompile("pA/fA08");
  
  while ((docInput=SxmlInputNextDocumentElement()))
    {
      SxmlNode *idno;
      char *inistDate;
      SxmlNode *teiDate;
      SxmlNode *teiTitle;
      SxmlNode *titleElem;
   
      if (!inistCreateRecord()) 
	{
	  exit (EXIT_FAILURE);
	}
      pascalKeywordFr=NULL;
      
      InistPA=SxmlGetFirstChildByTagName(standardNode,"pA");
      fA01=SxmlGetFirstChildByTagName(InistPA,"fA01");

      if (fA01)
	{
	  /* SxmlAppendChild(Tei_biblStruct, Tei_analytic=SxmlElementCreate("analytic")); */
	  SxmlAppendChild(Tei_biblStruct, Tei_series=SxmlElementCreate("series"));
	}

      fA14=SxmlGetFirstChildByTagName(InistPA,"fA14");
      fA47=SxPathFirstResultNode(inistPathA47,standardNode);
      if(fA47)
	{
	  SxmlAppendChild(Tei_publicationStmt, idno=SxmlLeafCreate("idno",SxmlLeafText(fA47)));
	  SxmlSetAttribute(idno, "type", "inist");
	}
	  
      /*                            
				    Titles
      */
      if ((fA08=SxPathFirstResultNode(inistPathA08,standardNode)))
	{
	  SxmlNode *fA08s1;
	  fA08s1=SxmlGetFirstChildByTagName(fA08,"s1");
	  SxmlAppendChild(Tei_titleStmt, teiTitle=SxmlElementCreate("title"));
	  if (!Tei_analytic) SxmlAppendChild(Tei_biblStruct, Tei_analytic=SxmlElementCreate("analytic"));
	  SxmlReset(fA08s1);
	  while ((titleElem=SxmlNextNode(fA08s1))) SxmlAppendChild(teiTitle, SxmlClone (titleElem));
	  SxmlSetAttribute(teiTitle, "xml:lang", inistGetFieldLang(fA08));
	  SxmlSetAttribute(teiTitle, "level", "a");
	  SxmlAppendChild(Tei_analytic, SxmlClone(teiTitle));
	}
      if ((fA09=SxmlGetFirstChildByTagName(InistPA,"fA09")))
	{
	  SxmlNode *fA09s1;
	  fA09s1=SxmlGetFirstChildByTagName(fA09,"s1");
	  if (fA08)         /* A08 + A09 */
	    {
	    }
	  else
	    {    
	      SxmlAppendChild(Tei_titleStmt, teiTitle=SxmlElementCreate("title"));
	      SxmlReset(fA09s1);
	      while ((titleElem=SxmlNextNode(fA09s1))) SxmlAppendChild(teiTitle, SxmlClone (titleElem));
	      SxmlSetAttribute(teiTitle, "xml:lang", inistGetFieldLang(fA09));
	      SxmlSetAttribute(teiTitle, "level", "m");
	    }
	}
      if ((fA21=SxmlGetFirstChildByTagName(InistPA,"fA21"))
	  && (fA21s1=SxmlGetFirstChildByTagName(fA21,"s1")))
	{
	  inistDate=SxmlLeafText(fA21s1);
	  SxmlAppendChild(Tei_publicationStmt, teiDate=SxmlLeafCreate("date",inistDate));
	  SxmlSetAttribute(teiDate, "when", inistDate);
	}
      else
	{
	  SxmlAppendChild(Tei_publicationStmt, teiDate=SxmlLeafCreate("date", "????"));
	  SxmlSetAttribute(teiDate, "when", "????");
	}
      
      if ((fA11=SxmlGetFirstChildByTagName(InistPA,"fA11")))
	{
	  iterAut(fA11);
	}
      if ((fA12=SxmlGetFirstChildByTagName(InistPA,"fA12")))
	{
	  iterA12(fA12);
	}
      if ((fA64=SxmlGetFirstChildByTagName(InistPA,"fA64")))  /* main title */
	{
	  char *titMain;
	  titMain=SxmlLeafText(SxmlGetFirstChildByTagName(fA64,"s0"));
	  TeiHandlerSetSeriesTitle(titMain, "j", "main");
	}
      if ((fA03=SxmlGetFirstChildByTagName(InistPA,"fA03")))  /* abbrev */
	{
	  char *titAb;
	  titAb=SxmlLeafText(SxmlGetFirstChildByTagName(fA03,"s0"));
	  TeiHandlerSetSeriesTitle(titAb, "j", "abbreviated");
	}
      if (fA01)  /* ISSN */
	{
	  char *issn;
	  SxmlNode *imprint;
	  issn=SxmlLeafText(SxmlGetFirstChildByTagName(fA01,"s0"));
	  TeiHandlerSetIssn(issn);
	  SxmlAppendChild(Tei_series, imprint=SxmlElementCreate("imprint"));
	  if(fA21s1)
	    {
	      char *inistDate;
	      inistDate=SxmlLeafText(fA21s1);
	      SxmlAppendChild(imprint, teiDate=SxmlLeafCreate("date",inistDate));
	      SxmlSetAttribute(teiDate, "when", inistDate);
	    }
	}
      
      if ((fC03=SxmlGetFirstChildByTagName(InistPA,"fC03")))
	{
	  iterKw(fC03);
	}
      if ((fC01=SxmlGetFirstChildByTagName(InistPA,"fC01")))
	{
	  TeiHandlerStoreAbstract(SxmlGetFirstChildByTagName(fC01,"s0"), inistGetFieldLang(fC01));
	}

      computeId();
      SxmlPrint(record);
      putchar('\n');
      SxmlFree(record);
    }
   exit (EXIT_SUCCESS);
}
