
#include "RobboLito_def.h"
#include "RobboTripleBase.h"
#include <string.h>
#include "RobboTotalBase.h"

int TRIPLE_BASE_TABLE[16][16][16][16];
void EmitTripleFileNames (Type_PiSq * PiSq, char * BUFFER)
{
  int j, v;
  v = TRIPLE_BASE_TABLE[PiSq->pi[0]][PiSq->pi[1]][PiSq->pi[2]][PiSq->pi[3]];
  if (v != -1)
    {
      RobboTripleBase* TRIPLE;
      v = v & 0xffff;
      TRIPLE = TABLE_TRIPLE_BASES + v;
      strcat (BUFFER, TRIPLE->path);
      strcat (BUFFER, " ");
      for (j = 0; j < 4; j++)
	if (TRIPLE->efgh[j] != -1 && TRIPLE->efgh[j] != 0xffff)
	  {
	    int w = TRIPLE->efgh[j] & 0xffff;
	    if (w == v)
	      continue;
	    strcat (BUFFER, (TABLE_TRIPLE_BASES + w)->path);
	    strcat (BUFFER, " ");
	  }
    }
}

void TripleFileInfo (RobboTripleBase*, char *);
void EmitTripleFilesInfo (Type_PiSq * PiSq, char * BUFFER)
{
  int v, i;
  RobboTripleBase* TRIPLE;
  if (!PiSq->wtm)
    for (i = 0; i < 4; i++)
      PiSq->pi[i] = col_scamb[PiSq->pi[i]];
  v = TRIPLE_BASE_TABLE[PiSq->pi[0]][PiSq->pi[1]][PiSq->pi[2]][PiSq->pi[3]];  
  if (!PiSq->wtm)
    for (i = 0; i < 4; i++)
      PiSq->pi[i] = col_scamb[PiSq->pi[i]];
  if (v == -1)
    {
      strcat (BUFFER, "Error in TABLE determinative (Triple)\n");
      return;
    }
  v = v & 0xffff;
  TRIPLE = TABLE_TRIPLE_BASES + v;
  TripleFileInfo (TRIPLE, BUFFER);
  for (i = 0; i < 4; i++)
    if (TRIPLE->efgh[i] != -1 && TRIPLE->efgh[i] != 0xffff)
      {
	int w = TRIPLE->efgh[i] & 0xffff;
	if (v == w)
	  continue;
	TripleFileInfo (TABLE_TRIPLE_BASES + w, BUFFER);
      }
  strcat (BUFFER, "TripleFilesInfo complete\n\n");
}

void DoIndexVerify (RobboTripleBase *, char *, int);

#define DO_INDEX_VERIFY TRUE
void TripleFileInfo (RobboTripleBase * TRIPLE, char * BUFFER)
{
  char STRING[0x1000];
  int heaps, i;
  sprintf (STRING, "** The filename identifies to %s\n", TRIPLE->path);
  strcat (BUFFER, STRING);
  sprintf (STRING, "There are " TYPE_64_BIT " positions\n", TRIPLE->size);
  strcat (BUFFER, STRING);
  if (TRIPLE->w[2] == 0)
    {
      sprintf (STRING, "The file has one result: %d\n", TRIPLE->w[1]);
      strcat (BUFFER, STRING);
      strcat (BUFFER, "Done with this Triple file\n");
      return;
    }
  if (!(TRIPLE->variant & ROBBO_DYNAMIC_LOAD))
    {
      strcat (BUFFER, "The file is in Direct Load mode\n");
      sprintf (STRING, "This entails %d bytes of data\n", TRIPLE->by);
      strcat (BUFFER, STRING);
      sprintf (STRING, "This entails %d index bytes\n", 4 + 4 * TRIPLE->index);
      strcat (BUFFER, STRING);
      return;
    }
  strcat (BUFFER, "The file is in Dynamic Load mode\n");
  heaps = 1 + (TRIPLE->size >> 30);
  sprintf (STRING, "There are %d heaps\n", heaps);
  strcat (BUFFER, STRING);
  for (i = 0; i < heaps; i++)
    {
      sprintf (STRING, "Heap number %d has %d packets (256k each -> %dmb)\n",
	       i, TRIPLE->packet_count[i], 1 + (TRIPLE->packet_count[i] >> 2));
      strcat (BUFFER, STRING);
      if (DO_INDEX_VERIFY)
	DoIndexVerify (TRIPLE, BUFFER, i);
    }
}

#define CHECK_BYTE(x, y) \
  if (x != y) { sprintf (STRING, "Bad Triple watermark %s %d %d %d\n", \
			 TRIPLE->string, TRIPLE->num, heap, j); \
                strcat (BUFFER, STRING); return; }

void OpenTripleFile (RobboTripleBase*);
void DoIndexVerify (RobboTripleBase * TRIPLE, char * BUFFER, int heap)
{
  char STRING[0x1000];
  uint32 INDEX[0x1220];
  int j, ind, bytes, lim1, index_count, i1, i2, i;
  if (!TRIPLE->disk)
    OpenTripleFile (TRIPLE);
  for (j = TRIPLE->packet_count[heap] - 1; j < TRIPLE->packet_count[heap]; j++)
    {
      fseek (TRIPLE->disk, TRIPLE->packet_offset[heap][j], SEEK_SET);
      CHECK_BYTE (fgetc (TRIPLE->disk), 0xf2);
      CHECK_BYTE (fgetc (TRIPLE->disk), 0x77);
      CHECK_BYTE (fgetc (TRIPLE->disk), 0x83);
      CHECK_BYTE (fgetc (TRIPLE->disk), 0x83);
      fread (&ind, 4, 1, TRIPLE->disk);
      fread (&bytes, 4, 1, TRIPLE->disk);
      fread (INDEX, 4, ind, TRIPLE->disk);
      index_count = (bytes + 0x3f) / 0x40;
      lim1 = (index_count + 255) / 0x100;

      for (i = 0; i < 16; i++)
	if ((i || j) && (INDEX[i] >> 2) == 0)
	  {
	    sprintf (STRING, "Bad Index: packet %d lev1 entry %d\n", j, i);
	    strcat (BUFFER, STRING);
	  }
      for (i = 0; i < index_count; i++)
	if ((i || j) && (INDEX[ind - index_count + i] >> 2) == 0)
	  {
	    sprintf (STRING, "Bad Index: packet %d lev3 %d %d %d\n",
		     j, i >> 8, (i >> 4) & 0xf, i & 0xf);
	    strcat (BUFFER, STRING);
	  }
      for (i1 = 0; i1 < lim1; i1++)
	for (i2 = 0; i2 < 0x10; i2++)
	  if ((i1 || i2 || j) && (INDEX[((i1 + 1) << 5) + i2] >> 2) == 0)
	  {
	    sprintf (STRING, "Bad Index: packet %d lev2 %d %d\n", j, i1, i2);
	    strcat (BUFFER, STRING);
	  }      
    }    
}
