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

#include "iotrace.h"

#define InputFileNum 10

#define DriveNum 8

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


int NextTrace(int flag[])
{
  /*for (int i = 0; i < InputFileNum; i++)
    if (flag[i])
      return i;
  return 0;
  */
  
  int alltickets = 0;

  for (int i = 0; i < InputFileNum; i++)
    if (flag[i])
      alltickets += NextTraceSeed[i];

  int chooseticket = random() % alltickets;

  for (int i = 0; i < InputFileNum; i++)
    if (flag[i]) {
      chooseticket -= NextTraceSeed[i]; 
      if (chooseticket < 0) 
	return i;
    }
  
  return 0;
  
}

void ModTraceRec(struct tracerecord &record, int index, int drivenum)
{
  // syn1.
  //record.i_dev = index % drivenum;

  // syn2.
  //record.i_dev = 1;

  // syn3.
  // do nothing
  if (record.i_dev == 5382)
    record.i_dev = 0;
  else 
    record.i_dev = 1;

  // syn4.
  //if (index == 0)
  //  record.i_dev = 0;
  //else 
  //  record.i_dev = 1;

  // syn5.
  //if ((index == 0) || (index == 1) || (index == 2))
  //  record.i_dev = index;

  //else if ((index >= 3) && (index <= 5))
  //record.i_dev = 3;

  //else if ((index >= 6) && (index <= 8))
  //record.i_dev = 4;

  //else 
    //record.i_dev = random() % 3 + 5;
  //record.i_dev = 5;
}

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

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

  if (outfp == NULL) {
    printf("output file open error\n");
    exit(1);
  }

  // open input file
  FILE *fp[InputFileNum];

  fp[0] = fopen("trace/j1-trace.trace", "r");
  fp[1] = fopen("trace/j2-trace.trace", "r");
  fp[2] = fopen("trace/j3-trace.trace", "r");
  fp[3] = fopen("trace/j4-trace.trace", "r");
  fp[4] = fopen("trace/j5-trace.trace", "r");
  fp[5] = fopen("trace/j6-trace.trace", "r");
  
  fp[6] = fopen("trace/bigsort-trace.trace", "r");
  fp[7] = fopen("trace/pjoin-trace.trace", "r");
  fp[8] = fopen("trace/pq7-trace.trace", "r");
  fp[9] = fopen("trace/xds-trace.trace", "r");

  for (int i = 0; i < InputFileNum; i++)
    if (fp[i] == NULL) {
      printf("File Open Error\n");
      exit(1);
    }

  // synthesis
  int inputleft = InputFileNum;
  int flag[InputFileNum];

  struct tracerecord record;

  int size;

  // init flag, all the input trace files are open
  for (int i = 0; i < InputFileNum; i++)
    flag[i] = 1;

  while (inputleft > 0) {

    // decide where does next trace come from
    int index = NextTrace(flag);

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

	  ModTraceRec(record, index, DriveNum);
	  
	  fwrite(&record, sizeof(struct tracerecord), 1, outfp);

	  break;

	}
      }
    }

    // end of the file
    if (size == 0) {  
      inputleft--;
      flag[index] = 0;
    }
  }

  // close file
  fclose(outfp);
  for (int i = 0; i < InputFileNum; i++)
    fclose(fp[i]);

}
