#include <fstream>
#include <iostream>

using namespace std;

int low, high;
string path1, path2;

bool readUntil(ifstream& ifs, const string& s)
{
  char c;  
  int pos = 0;
  ifs.get(c);
  while (!ifs.eof()) {
    if (c == s[pos]) {
      ++pos;
      if (s[pos] == '\0') return true;
    }
    else {
      ifs.putback(c);
      while (pos != 0) {
        pos--;
        ifs.putback(s[pos]);
      }
      ifs.get(c);
    }
    ifs.get(c);
  }
}

bool readResult(ifstream& ifs, int& splitters, float& time, bool& valid)
{
  char c;
  float userTime, sysTime;
  if (!readUntil(ifs, "Running")) return false;
  if (!readUntil(ifs, "***")) return false;
  ifs.get(c);
  ifs.get(c);
  if (c == 'V') valid = true;
  else if (c == 'I') valid = false;
  else {
    cout << "Trouble1: " << c << endl;
    exit(-1);
  }  
  if (!readUntil(ifs, "splitters = ")) return false;
  ifs >> splitters;
  if (!readUntil(ifs, "user\t0m")) return false;
  ifs >> userTime;
  if (!readUntil(ifs, "sys\t0m")) return false;
  ifs >> sysTime;
  time = userTime + sysTime;
  return true;
}


int doFile(const string& filename,
           int& splitters1, int& splitters2,
           float& time1, float& time2,
           int& valid1, int& valid2,
           int& invalid1, int& invalid2
           )
{
  int sp1, sp2, count = 0, total = 0;
  float t1, t2;
  ifstream file1, file2;
  bool v1, v2;
  string f = path1+filename;
  file1.open(f.c_str());
  f = path2+filename;
  file2.open(f.c_str());
  if (file1.is_open()) {
    while (!file1.eof()) {
      if (!readResult(file1, sp1, t1, v1)) break;
      if (!readResult(file2, sp2, t2, v2)) break;
      total++;
      if (!(sp1 < low && sp2 < low) &&
          (sp1 <= high && sp2 <= high)) {
        count++;
        splitters1 += sp1;
        splitters2 += sp2;
        time1 += t1;
        time2 += t2;
        if (v1) valid1++;
        else invalid1++;
        if (v2) valid2++;
        else invalid2++;
        if (v1 != v2) cout << "Oops" << endl;
      }
    }
    file1.close();
    file2.close();
  }
  if (total != 800) {
    cout << "Trouble: total = " << total << endl;
    exit(-1);
  }
  cout << filename << ": total: " << total << ", count: " << count << endl;
  return count;
}

int main(int argc, char **argv)
{
  if (argc != 5) {
    cout << "Usage: reports <dir1> <dir2> <splitters-low> <splitters-high>" << endl;
    exit(-1);
  }
  path1 = argv[1];
  path2 = argv[2];
  low = atoi(argv[3]);
  high = atoi(argv[4]);
  cout << "Searching for testcases with worst-case splitters from " << low
       << " to " << high << "." << endl;
  int count = 0, sp1 = 0, sp2 = 0;
  float time1 = 0.0, time2 = 0.0;
  int v1 = 0, v2 = 0, iv1 = 0, iv2 = 0;
  //  count += doFile("tmp", sp1, sp2, time1, time2);
  count += doFile("tests_v1_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("tests_v2_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("tests_v3_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("tests_v5_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("tests_v10_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("typed_v1_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("typed_v2_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("typed_v3_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("typed_v5_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);
  count += doFile("typed_v10_no_tcc.log", sp1, sp2, time1, time2, v1, v2, iv1, iv2);

  cout << "Count: " << count << endl;
  cout << "Splitters (first): " << sp1 << endl;
  cout << "Splitters (second): " << sp2 << endl;
  cout << "Time (first): " << time1 << endl;
  cout << "Time (second): " << time2 << endl;
  cout << "Valid (first): " << v1 << endl;
  cout << "Valid (second): " << v2 << endl;
  cout << "Invalid (first): " << iv1 << endl;
  cout << "Invalid (second): " << iv2 << endl;

}

