/*   -*- coding: utf-8 -*-  */
/******************************************************************************
*
*               Module   : Explor
*               Fichier  : ExplorGenerTemplateSize.c
*               Auteur   : J. DUCLOY
******************************************************************************/

#include "SxmlNode.h"
#include "MediaWiki.h"
#include "Explor.h"
#include "HfdIndex.h"
#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>
#include <time.h>

SxmlNode *ExplorTemplateDataTreeSetValue(char *stream, char *step, char *indexName, char *key, char *value);

int   ExplorGenerTraceLevel;
SxmlNode *ExplorTemplateListTop;
FILE *popenFile;
FILE *popen();
char *bufPopen;

char *ExplorHfdSize(char *stream, char *step, char *hfdRoot)
{
  static Buffer *bufPath=NULL;
  SxmlNode *hcsRoot;
  if (!bufPath)bufPath=NewBuffer();

  BufferStrcpy(bufPath, ExplorAreaDir);
  BufferStrcat(bufPath,"/Data/");
  BufferStrcat(bufPath,stream);
  BufferStrcat(bufPath,"/");
  BufferStrcat(bufPath,step);
  BufferStrcat(bufPath,"/");
  BufferStrcat(bufPath,hfdRoot);
  BufferStrcat(bufPath,".hcs");
  hcsRoot=SxmlFromFile(BufferString(bufPath));
  return SxmlLeafText(SxmlGetFirstChildByTagName(hcsRoot,"nrec"));
} 

SxmlNode *ExplorHfdReadKey(char *stream, char *step, char *index, char *key)
{
  static Buffer *oldStream=NULL;
  static Buffer *oldStep=NULL;
  static Buffer *oldIndex=NULL;
  static Buffer *bufPath=NULL;
  static HfdIndex  *indexReader;
  SxmlNode *indexNode;
  int openMustBeDone;

  openMustBeDone=0;
  if (!oldStream)
    {
      openMustBeDone=1;
      oldStream=BufferFromString(stream);
      oldStep=BufferFromString(step);
      oldIndex=BufferFromString(index);
      bufPath=NewBuffer();
    }
  else
    {
      if ((strcmp(index, BufferString(oldIndex))==0) && (strcmp(step, BufferString(oldStep))==0) && (strcmp(stream, BufferString(oldStream))==0))
	openMustBeDone=0;
      else
	{
	  BufferStrcpy(oldIndex, index);
	  BufferStrcpy(oldStep, step);
	  BufferStrcpy(oldStream, stream);
	  HfdIndexClose(indexReader);
	  openMustBeDone=1;
	}
    }
  if (openMustBeDone==1)
    {
      BufferStrcpy(bufPath,ExplorAreaDir);
      BufferStrcat(bufPath, "/Data/");
      BufferStrcat(bufPath, stream);
      BufferStrcat(bufPath, "/");
      BufferStrcat(bufPath, step);
      BufferStrcat(bufPath, "/");
      BufferStrcat(bufPath, index);
      BufferStrcat(bufPath, ".i");
      indexReader=HfdIndexOpenRead(BufferString(bufPath));
      if (!indexReader)return NULL;
    }
  indexNode=HfdIndexReadSxml(indexReader, key);
  return indexNode;
}

SxmlNode *ExplorTemplateDataTreeSetValue(char *stream, char *step, char *indexName, char *key, char *value)
{
  SxmlNode *streamNode;
  SxmlNode *stepNode;
  SxmlNode *indexNode;
  SxmlNode *keyNode;
  char *indexHfdCode;
  static Buffer *bufName=NULL;
  
  if (!bufName) bufName=NewBuffer();
  BufferStrcpy(bufName, indexName);
  BufferStrcat(bufName, ".i");
  indexHfdCode=BufferString(bufName);
  streamNode=SxmlGetFirstChildTagAtt(ExplorTemplateDataTree, "stream", "code", stream);
  if (!streamNode) return NULL;
  SxmlSetAttribute(streamNode, "key", "active");
  stepNode=SxmlGetFirstChildTagAtt(streamNode, "step", "code", step);
  if (!stepNode) return NULL;
  SxmlSetAttribute(stepNode, "key", "active");
  indexNode=SxmlGetFirstChildTagAtt(stepNode, "index", "code", indexHfdCode);
  if (!indexNode) return NULL;
  SxmlSetAttribute(indexNode, "key", "active");
  SxmlAppendChild(indexNode, keyNode=SxmlLeafCreate("key", key));
  SxmlSetAttribute(keyNode, "value", value);
  return keyNode;
}

SxmlNode *ExplorTemplateIndexReadAndSet(char *stream, char *step, char *indexName, char *key)
{
  SxmlNode *indexFrNode;
  SxmlNode *indexNode;
  indexNode=ExplorHfdReadKey(stream, step, indexName, key);
  if (!indexNode) return NULL;
  indexFrNode=SxmlGetFirstChildByTagName(indexNode, "f");
  ExplorTemplateDataTreeSetValue(stream, step, indexName, key, SxmlLeafText(indexFrNode));
  return indexNode;
}

/* SxmlDocumentReader *ExplorSortReader=NULL; */

SxmlNode *ExplorGenerTemplateDataTreeSetTop(char *stream, char *step, char *indexHfdCode, int nTop)
{
  static Buffer *bufPath=NULL;
  SxmlNode *sortNode;
  SxmlNode *topNode;
  int i;
  if (!bufPath)bufPath=NewBuffer();
  if(!ExplorSortReader)ExplorSortReader=SxmlRecordReaderCreate();

  topNode=SxmlElementCreate("top");
  SxmlAppendChild(ExplorTemplateListTop, topNode);
  SxmlSetAttribute(topNode, "stream", stream);
  SxmlSetAttribute(topNode, "step", step);
  SxmlSetAttribute(topNode, "index", indexHfdCode);
  BufferStrcpy(bufPath,ExplorAreaDir);
  BufferStrcat(bufPath, "/Data/");
  BufferStrcat(bufPath, stream);
  BufferStrcat(bufPath, "/");
  BufferStrcat(bufPath, step);
  BufferStrcat(bufPath, "/");
  BufferStrcat(bufPath, indexHfdCode);
  BufferStrcat(bufPath, ".i.sort");
  if (ExplorGenerTraceLevel > 0) printf("%s\n", BufferString(bufPath));
  SxmlRecordReaderOpen(ExplorSortReader, BufferString(bufPath));
  i=nTop;
  while((i--)&& (sortNode=SxmlRecordReaderNextDocumentElement(ExplorSortReader)))
    {
      SxmlNode *keyNode;
      SxmlNode *sizeNode;
      keyNode=SxmlGetFirstChildByTagName(sortNode,"kw");
      sizeNode=SxmlGetFirstChildByTagName(sortNode,"f");
      ExplorTemplateDataTreeSetValue(stream, step, indexHfdCode, SxmlLeafText(keyNode), SxmlLeafText(sizeNode));
    }
  
  return sortNode;
}

void ExplorGenerTemplateSize()
{
  SxmlNode *streamNode;
  int pmcCheckpointSize;
  int pubmedCheckpointSize;
  int mainCorpusSize;
  int ncbiCorpusSize;
  int areaChekpointSize;

  pmcCheckpointSize=0;
  pubmedCheckpointSize=0;
  mainCorpusSize=0;
  ncbiCorpusSize=0;
  areaChekpointSize=0;
  ExplorGenerTemplateInit("Explor size");
  MediaWikiExportPageBegin(ExplorTemplateName, getenv("USER"), NULL);
  printf ("{{#switch:{{{stream}}}");
  SxmlReset(ExplorAreaData);
  while ((streamNode=SxmlNextNode( ExplorAreaData)))
    {
      char *streamType;
      if (SxmlNodeHasName(streamNode, "stream"))
	{
	  char *codeStream;
	  SxmlNode *stepNode;
	  streamType=SxmlGetAttribute(streamNode, "type");
	  if (SxmlHasAttribute(streamNode, "group", "up")) ExplorAreaIsMulti=1;
	  codeStream=SxmlGetAttribute(streamNode,"code");
	  printf("|%s=", codeStream);
	  printf ("{{#switch:{{{step}}}");
	  if (strcmp(streamType, "Nlm:Ncbi")==0)
	    {
	      printf("|Corpus={{#switch:{{{index}}}|biblio=%d}}", pmcCheckpointSize+pubmedCheckpointSize);
	    }
	  SxmlReset(streamNode);
	  while ((stepNode=SxmlNextNode(streamNode)))
	    {
	      char *codeStep;
	      SxmlNode *indexNode;
	      if (SxmlNodeHasName(stepNode, "step"))
		{
		  char *sizeBiblio;
		  codeStep=SxmlGetAttribute(stepNode,"code");
		  printf("|%s=", codeStep);
		  printf ("{{#switch:{{{index}}}");
		  printf ("|biblio=%s\n", sizeBiblio=ExplorHfdSize(codeStream, codeStep, "biblio"));
		  if (((strcmp(streamType,"Inist:Stanalyst")==0)
		       ||((strcmp(streamType,"Inist:StanalystSolo")==0)))
		      &&((strcmp(codeStep,"Corpus")==0)))
		    {
		      static Buffer *bufScript=NULL;
		      if (!bufScript) bufScript=NewBuffer();
		      BufferStrcpy(bufScript, "HfdCat $EXPLOR_AREA/Data/");
		      BufferStrcat(bufScript, codeStream);
		      BufferStrcat(bufScript, "/Corpus/RBID.i.hfd | grep francis | wc -l");
		      popenFile=popen(BufferString(bufScript), "r");
		      /* popenFile = popen("HfdCat $EXPLOR_AREA/Data/PascalFrancis/Corpus/RBID.i.hfd | grep francis | wc -l", "r"); */
		      fgets(bufPopen, 20, popenFile);
		      printf ("|biblioFrancis=%s\n", bufPopen);
		      pclose(popenFile);
		      BufferStrcpy(bufScript, "HfdCat $EXPLOR_AREA/Data/");
		      BufferStrcat(bufScript, codeStream);
		      BufferStrcat(bufScript, "/Corpus/RBID.i.hfd | grep pascal | wc -l");
		      popenFile=popen(BufferString(bufScript), "r");
		     /*popenFile = popen("HfdCat $EXPLOR_AREA/Data/PascalFrancis/Corpus/RBID.i.hfd | grep pascal | wc -l", "r"); */
		      fgets(bufPopen, 20, popenFile);
		      printf ("|biblioPascal=%s\n", bufPopen);
		      pclose(popenFile);
		    }
		  SxmlSetAttribute(stepNode, "sizeBiblio", sizeBiblio);
		  if (strcmp(codeStep, "Checkpoint")==0)
		    {
		      if (strcmp(streamType, "Nlm:Pmc")==0) pmcCheckpointSize=atoi(sizeBiblio);
		      else if (strcmp(streamType, "Nlm:Medline")==0) pubmedCheckpointSize=atoi(sizeBiblio);
		      else  areaChekpointSize+=atoi(sizeBiblio);
		    }
		  SxmlReset(stepNode);
		  while((indexNode=SxmlNextNode(stepNode)))
		    {
		      if (SxmlNodeHasName(indexNode, "index"))
			{
			  char *indexCode;
			  static Buffer* bufIndexName=NULL;
			  if (!bufIndexName) bufIndexName=NewBuffer();
			  indexCode=SxmlGetAttribute(indexNode, "code");
			  BufferStrcpy(bufIndexName, indexCode);
			  BufferTailCut(bufIndexName,2);
			  printf ("|%s=%s\n", BufferString(bufIndexName), ExplorHfdSize(codeStream, codeStep, indexCode));
			}
		    }
		  printf("}}\n");
		}
	    }
          printf("   }}\n");
	}
    }	  
  printf ("\n");
  if(ExplorAreaIsMulti==1)
    {
      int sizeArea;
      printf("|Area={{#switch:{{{step}}}|Corpus={{#switch:{{{index}}}|biblio=");
      sizeArea=0;
      SxmlReset(ExplorAreaData);
      while ((streamNode=SxmlNextNode( ExplorAreaData)))
	{
	  SxmlNode *stepNode;
	 if (SxmlHasAttribute(streamNode, "group", "up"))
	   {
	     SxmlReset(streamNode);
	     while ((stepNode=SxmlNextNode(streamNode)))
	       {
		 char *sizeBiblioStr;
		 int sizeBiblio;
		 if (SxmlHasAttribute( stepNode, "code", "Corpus"))
		   {
		     sizeBiblioStr=SxmlGetAttribute(stepNode, "sizeBiblio");
		     sizeBiblio=atoi(sizeBiblioStr);
		     sizeArea+=sizeBiblio;
		   }
	       }
	   }
	}
      printf("%d}}", sizeArea);
      printf("|Checkpoint={{#switch:{{{index}}}|biblio=%d}}",areaChekpointSize);
      printf("}}\n");
    }
  printf ("}}");
  MediaWikiExportPageEnd();
}

char *resetQuoteFromText(char* key)
{
  char *posQuote;
  static Buffer *bufQuote=NULL;
  posQuote=strchr(key, '\'');
  if(!posQuote)return key;
  if (!bufQuote) bufQuote=NewBuffer();
  BufferStrncpy(bufQuote, key, posQuote-key);
  BufferStrcat(bufQuote," ");
  BufferStrcat(bufQuote, posQuote+1);
  return BufferString(bufQuote);
}

void ExplorGenerTemplateSizeKey()
{
  SxmlNode *streamNode;

  ExplorGenerTemplateInit("Explor size key");
  MediaWikiExportPageBegin(ExplorTemplateName, getenv("USER"), NULL);
  printf ("{{#switch:{{{stream}}}\n");
  SxmlReset(ExplorTemplateDataTree);
  while ((streamNode=SxmlNextNode(ExplorTemplateDataTree)))
    {
      if ((SxmlNodeHasName(streamNode, "stream") &&(SxmlHasAttribute(streamNode,"key", "active"))))
	{
	  char *codeStream;
	  SxmlNode *stepNode;
	  codeStream=SxmlGetAttribute(streamNode,"code");
	  printf("   |%s=", codeStream);
	  printf ("{{#switch:{{{step}}}\n");
	  SxmlReset(streamNode);
	  while ((stepNode=SxmlNextNode(streamNode)))
	    {
	      char *codeStep;
	      SxmlNode *indexNode;
	      if ((SxmlNodeHasName(stepNode, "step") &&(SxmlHasAttribute(stepNode,"key", "active"))))
		{
		  codeStep=SxmlGetAttribute(stepNode,"code");
		  printf("   |%s=", codeStep);
		  printf ("{{#switch:{{{index}}}\n");
		  SxmlReset(stepNode);
		  while((indexNode=SxmlNextNode(stepNode)))
		    {
		      if ((SxmlNodeHasName(indexNode, "index")) &&(SxmlHasAttribute(indexNode,"key", "active")))
			{
			  char *indexCode;
			  SxmlNode *keyNode;
			  static Buffer* bufIndexName=NULL;
			  if (!bufIndexName) bufIndexName=NewBuffer();
			  indexCode=SxmlGetAttribute(indexNode, "code");
			  BufferStrcpy(bufIndexName, indexCode);
			  BufferTailCut(bufIndexName,2);
			  printf ("    |%s=", BufferString(bufIndexName));
			  printf ("{{#switch:{{{key}}}\n");
			  SxmlReset(indexNode);
			  while((keyNode=SxmlNextNode(indexNode)))
			    {
			      if ((SxmlNodeHasName(keyNode, "key")))
				{
				  printf("       | %s = %s\n", resetQuoteFromText(SxmlLeafText(keyNode)), SxmlGetAttribute(keyNode, "value"));
				}
			    }
			  printf("}}\n");
			}
		    }
		  printf("}}\n");
		}
	    }
          printf("   }}\n");
	}
    }	  
  printf ("\n");
  printf ("}}\n");
  MediaWikiExportPageEnd();
}

void ExplorGenerTemplateSetTreeFromFile(char *filePath)
{
  SxmlNode *commandNode;
  static SxmlDocumentReader *paramReader=NULL;
  if (!paramReader) paramReader=SxmlRecordReaderCreate();
  SxmlRecordReaderOpen(paramReader, filePath);
  while ((commandNode=SxmlRecordReaderNextDocumentElement(paramReader)))
    {
      char *stream;
      char *step;
      char *index;
      SxmlNode *commandList;
      SxmlNode *paramNode;
      SxmlNode *commandItemNode;
      char *commandType;
      stream=SxmlLeafText(SxmlGetFirstChildByTagName(commandNode,"c1"));
      step=SxmlLeafText(SxmlGetFirstChildByTagName(commandNode,"c2"));
      index=SxmlLeafText(SxmlGetFirstChildByTagName(commandNode,"c3"));
      commandList=SxmlGetFirstChildByTagName(commandNode,"c4");
      commandType=SxmlLeafText(commandItemNode=SxmlFirstChild(commandList));
      paramNode=SxmlNextSibling(commandItemNode);
      if (*commandType=='l')  /* list */
	{
	  while(paramNode)
	    {
	      static Buffer *bufCom=NULL;
	      char *paramKey;
	      if(!bufCom) bufCom=NewBuffer();
	      paramKey=SxmlLeafText(paramNode);
	      if (*paramKey=='[')
		{
		  BufferStrcpy(bufCom, paramKey+2);
		  BufferTailCut(bufCom,2);
		  ExplorTemplateIndexReadAndSet(stream, step, index, BufferString(bufCom));
		}
	      else
		{
		  ExplorTemplateIndexReadAndSet(stream, step, index, paramKey);
		}
	      paramNode=SxmlNextSibling(paramNode);
	    }
	}
      else                   /* top */
	{
	  int lTop;
	  lTop=atoi(SxmlLeafText(paramNode));
	  ExplorGenerTemplateDataTreeSetTop(stream, step, index, lTop);
	}
    }
}




int main(int argc, char **argv)
{
  int cOption;
  int pageMode;        /*       si 1 ne pas générer début et fin de fichier */

  ExplorTemplateCurrentStream="Main";
  ExplorTemplateCurrentStep="Exploration";
  ExplorTemplateCurrentIndex="AffOrg";
  ExplorTemplateListTop=SxmlElementCreate("list");
  ExplorGenerTraceLevel=0;
  bufPopen=malloc(100);
  pageMode=0;

  while((cOption=getopt(argc,argv,"a:d:e:f:k:ps:S:i:t:T:"))!=EOF)
    /* 
         a : areaName
         d : area directory
         e : area env
         f : file keys (from wiki)
	 k : key
         p : mode page
         s : step
         S : stream
         i : index
         t : top lenght
         T : trace level
     */
     {switch (cOption)
	 {
	 case 'f':
	   if (!ExplorTableParam) ExplorGenerTemplateInitExplor();
	   ExplorGenerTemplateSetTreeFromFile(optarg);
	   break;
	 case 'i':
	   ExplorTemplateCurrentIndex=optarg;
	   break;
	 case 'k':
	   if (!ExplorTableParam) ExplorGenerTemplateInitExplor();
	   ExplorTemplateIndexReadAndSet(ExplorTemplateCurrentStream, ExplorTemplateCurrentStep, ExplorTemplateCurrentIndex, optarg);
	   break;
	 case 'p':
	   pageMode=1;
	   break;
	 case 's':
	   ExplorTemplateCurrentStep=optarg;
	   break;
	 case 'S':
	   ExplorTemplateCurrentStream=optarg;
	   break;
	 case 'T':
	   ExplorGenerTraceLevel=atoi(optarg);
	   break;
	 case 't':
	   if (!ExplorTableParam) ExplorGenerTemplateInitExplor();
	   ExplorGenerTemplateDataTreeSetTop(ExplorTemplateCurrentStream, ExplorTemplateCurrentStep, ExplorTemplateCurrentIndex, atoi(optarg));
	   break;
	 }
     }
  if (!ExplorTableParam) ExplorGenerTemplateInitExplor();
  if (ExplorGenerTraceLevel > 0)
    {
      SxmlPrint(ExplorTemplateDataTree);
      putchar ('\n');
    }
  if (pageMode==0) MediaWikiExportFileBegin();
  ExplorGenerTemplateSize();
  ExplorGenerTemplateSizeKey();
  if (pageMode==0) MediaWikiExportFileEnd();
  exit(EXIT_SUCCESS);
}
