#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"


#define WS ", \t"   /* whitespaces, ie. space, tab */
#define REM ";\n"   /* remark character */

#define CACHE_LRU           1
#define CACHE_LFU           2
#define CACHE_SIZE          3
#define CACHE_PARTITIONING  4


static char *get_line(FILE *fp)
{
  /*
   * from the current file position,
   * get the next line (for all lines ending with '\', to concatenate them)
   */

  static char result_line[MAX_LINE_LENGTH * 10];
  char line[MAX_LINE_LENGTH];
  int l, c;

  while (1) {
      if (fgets(line, MAX_LINE_LENGTH, fp) == NULL) {
  	  return NULL;
      }
      line[ strcspn(line, REM) ] = 0;
      l = strlen(line);
      c = strspn(line, WS);
      strncpy(line, line+c, l-c);
      line[l-c] = 0;
      if (line[0] != 0) {
  	  break;
      }
  }

  strcpy(result_line, "");
  while (1) {
      /* line[strlen(line) - 1] = 0; */
      line[strlen(line)] = 0;
      strcat(result_line, line);
      if (line[strlen(line)-1] == '\\') {    /* ie. char '\' */
  	  result_line[strlen(result_line) - 1] = 0; /* to remove the char '\' */
      } else {
  	  break;
      }

      while (1) {  /* to concatenate the lines following '\' */
  	  if (fgets(line, MAX_LINE_LENGTH, fp) == NULL) {
              /* return NULL; */
              return result_line;
  	  }
  	  line[ strcspn(line, REM) ] = 0;
  	  l = strlen(line);
  	  c = strspn(line, WS);
  	  strncpy(line, line+c, l-c);
  	  line[l-c] = 0;
  	  if (line[0] != 0) {
              break;
  	  }
      }
  }

  return result_line;
}

void do_other_cache_simulation_according_to_the_script_file(FILE *fp)
{
    int mode;
    char *line;
    INT   size, threshold, upgrading_threshold, window_size, throw_away;
    float ftmp, partition_ratio;


    while ( line = get_line(fp) ) {
        if (strcmp(line,"[cache_LRU]") == 0) {
            mode = CACHE_LRU;
        }
        else if (strcmp(line,"[cache_LFU]") == 0) {
            mode = CACHE_LFU;
        }
        else if (strcmp(line,"[cache_SIZE]") == 0) {
            mode = CACHE_SIZE;
        }
        else if (strcmp(line,"[cache_PARTITIONING]") == 0) {
            mode = CACHE_PARTITIONING;
        }
        else {
            switch (mode) {
              case CACHE_LRU:
                sscanf(line, "%f %lld", &ftmp, &threshold);
                size = (INT) (UniqueBytes * ftmp);
                threshold = (size<threshold ? size : threshold);
                fprintf(stderr,"Doing cache_LRU(size=%lld,threshold=%lld)...\n",
                                                     size,      threshold );
                cache_LRU(size, threshold);
                break;
              case CACHE_LFU:
                sscanf(line, "%f %lld", &ftmp, &threshold);
                size = (INT) (UniqueBytes * ftmp);
                threshold = (size<threshold ? size : threshold);
                fprintf(stderr,"Doing cache_LFU(size=%lld,threshold=%lld)...\n",
                                                     size,      threshold );
                cache_LFU(size, threshold);
                break;
              case CACHE_SIZE:
                sscanf(line, "%f %lld", &ftmp, &threshold);
                size = (INT) (UniqueBytes * ftmp);
                threshold = (size<threshold ? size : threshold);
                fprintf(stderr,"Doing cache_SIZE(size=%lld,threshold=%lld)...\n"
                                                 ,    size,      threshold );
                cache_SIZE(size, threshold);
                break;
              case CACHE_PARTITIONING:
                sscanf(line, "%f %f %lld %lld %lld %lld",
                       &ftmp, &partition_ratio, &threshold,
                       &upgrading_threshold, &window_size, &throw_away);
                size = (INT) (UniqueBytes * ftmp);
                threshold = (size<threshold ? size : threshold);
                fprintf(stderr,"Doing cache_PARTITIONING(size=%lld, ", size);
                fprintf(stderr,"partition_ratio=%f, ",partition_ratio);
                fprintf(stderr,"threshold=%lld, ",threshold);
                fprintf(stderr,"upgrading_threshold=%lld,",upgrading_threshold);
                fprintf(stderr," window_size=%lld, ",window_size);
                fprintf(stderr,"throw_away=%lld) ...\n",throw_away);
                cache_PARTITIONING(size, partition_ratio, threshold,
                                  upgrading_threshold, window_size, throw_away);
                break;
            }
        }
    }
}

