#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <strings.h>
#include <iostream.h>
#include <fstream.h>
#include <string>

#include "iotrace.h"
#include "synthe1.h"

#define SPARCECONSTANT 1000000

//static int NextTraceSeed[InputFileNum] = {96, 44, 62, 91, 143, 230, 50, 100, 80, 213}; 

Synthe::Synthe(char * confname)
{

  recnum = 0;

  char tmp[256];

  fstream input;

  inputleft = 0;

  //alltickets = 0;

  input.open(confname, ios::in);
  if (!input) {
    cout << "File Open Failed ! " << endl;
    exit(1);
  }

  input.seekg(0, ios::beg);
  while (input.getline(tmp, 256, '\n')) {
    if ((tmp[0] == 0)||(tmp[0] == ' ')||(tmp[0] == '\n')||(tmp[0] == '\r'))
      break;
  
    // open input file
    fp[inputleft] = fopen(strtok(tmp, " "), "r");
    if (fp[inputleft] == NULL) {
      cout << "File " << inputleft + 1 << "  Open Error" << endl;
      exit(1);
    }
    NextTraceSeed[inputleft] =  atoi(strtok(NULL, " "));
    
    //alltickets += NextTraceSeed[inputleft];
    DevnumTB[inputleft] = atoi(strtok(NULL, " "));
    offset[inputleft] = atoi(strtok(NULL, " \n"));
    flag[inputleft] = 1;
    inputleft++;
    if (inputleft > InputFileNum) {
      cout << "cannot have more than " << InputFileNum << " files " << endl;
      exit(1);
    }
  }

  inputfilenum = inputleft;
  //  cout << "trace coming from " << inputfilenum << " files" << endl;
  /*  cout << "next trace seeds: " << endl;
  for (int i = 0; i < inputleft; i++)
    cout << "  " << NextTraceSeed[i];
  cout << endl << "DevnumTB: " << endl;
  for (int i = 0; i < inputleft; i++)
    cout << "  " << DevnumTB[i];
    cout << endl;*/
  input.close();

  srandom(731419); // initialize the seed

  //  for (int i = 0 ; i < inputfilenum ; i ++)
  //  printf("index %d, device number %d\n", i, DevnumTB[i]);
}

Synthe::~Synthe()
{
  for (int i = 0; i < inputfilenum; i++)
    fclose(fp[i]);
}

void Synthe::printconfig(char * confname)
{
  char tmp[256];

  fstream input;

  printf("Trace: \n\n");
  input.open(confname, ios::in);
  if (!input) {
    cout << "File Open Failed ! " << endl;
    exit(1);
  }

  input.seekg(0, ios::beg);
  while (input.getline(tmp, 256, '\n')) {
    if ((tmp[0] == 0)||(tmp[0] == ' ')||(tmp[0] == '\n')||(tmp[0] == '\r'))
      break;
    printf(tmp);
    putchar('\n');
  }
  
  input.close();
  printf("\n\n");
}

int Synthe::NextTrace()
{

  while (inputleft > 0) {

    alltickets = 0;

    for (int i = 0; i < inputfilenum; i++)
      if (flag[i] && (offset[i] < recnum)) {
	alltickets += NextTraceSeed[i];
      }
    
    if (alltickets == 0) {
      recnum++;
      continue;
    }

    int chooseticket = random() % alltickets;
    
    for (int i = 0; i < inputfilenum; i++)
      if (flag[i] && (offset[i] < recnum)) {
	chooseticket -= NextTraceSeed[i]; 
	if (chooseticket < 0) 
	return i;
      }

  }
  
  return 0;
  
}

void Synthe::ModTraceRec(struct tracerecord &record, int index)
{
  record.pid = index; // user id;

  record.i_dev =  DevnumTB[index];
  //record.i_num += index;
  record.i_num = (index * SPARCECONSTANT) + record.i_num;
}

int Synthe::readrecord(struct tracerecord & record)
{
  while  (inputleft > 0) {

    int size;
    
    // where next trace come from
    int index = NextTrace();

    recnum++;

    while ((size = fread(&record, sizeof(struct tracerecord), 1, fp[index])) != 0) {
      
      if ((record.op >= MYTRACE_READ) && (record.op <= MYTRACE_EXIT)) {
      
	if ((record.i_dev == 5382) ||
	    (record.i_dev == 5418))
	  {
	  
	    ModTraceRec(record, index);
	  
	    return 1;
	  
	  }
      }
    }

    if (size == 0) {
      //      fclose(fp[index]);
      inputleft--;
      flag[index] = 0;

    }
  }

  return 0;
}

/*int main(int argc, char * argv[])
{

  // open output file
  if (argc < 3) {
    printf("usage: %s configfilename outputfilename\n", argv[0]);
    exit(1);
  }
  
  FILE *outfp = fopen(argv[2], "w");

  if (outfp == NULL) {
    printf("output file open error\n");
    exit(1);
  }
  
  // synthesis
  Synthe * synthe = new Synthe(argv[1]);

  struct tracerecord record;

  //  while (synthe->readrecord(record))
  //fwrite(&record, sizeof(struct tracerecord), 1, outfp);

  synthe->printconfig(argv[1], outfp);
  // close file
  fclose(outfp);
}*/




