#include <cstdio>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <ctime>
#include <vector>

#include "json.hpp"
#include "insertionsort.h"
#include "mergesort.h"
#include "quicksort.h"

int main(int argc, char* argv[]) {
  // read JSON file and store in jsonObject
  std::ifstream file;
  file.open(argv[1]);
  nlohmann::json jsonObject;
  // Store the contents filename into jsonObject
  if (file.is_open()) {
    file >> jsonObject;
  }

  // initiate CSV file quickto which data will be written
  /*
  std::ofstream theFile;
  theFile.open("timealgorithms.csv");
  theFile << "Sample,InsertionSortTime,InsertionSortCompares,InsertionSortMemaccess,MergeSortTime,MergeSortCompares,MergeSortMemaccess,QuickSortTime,QuickSortCompares,QuickSortMemaccess\n";
  */

  std::cout << "Sample,InsertionSortTime,InsertionSortCompares,InsertionSortMemaccess,MergeSortTime,MergeSortCompares,MergeSortMemaccess,QuickSortTime,QuickSortCompares,QuickSortMemaccess" << std::endl;

  // initialize arrays for JSON data
  // each should have it's own copy cause the array get's sorted within each function
  std::vector<int>* insArray = new std::vector<int>();
  std::vector<int>* merArray = new std::vector<int>();
  std::vector<int>* quickArray = new std::vector<int>();

  // initialize insertion sort variables
  int *insReturnArray;
  clock_t insStartTime;
  float insTime;
  // initialize merge sort variables
  int *mergeReturnArray;
  clock_t merStartTime;
  float merTime;
  // initialize quick sort variables
  int *quickReturnArray;
  clock_t quickStartTime;
  float quickTime;

  std::string sampleName;     // Sample key name to iterate

  for (auto itr = jsonObject.begin(); itr != jsonObject.end(); ++itr) {
    sampleName = itr.key();

    if (sampleName != "metadata") {
      for (auto arrayItr = jsonObject[sampleName].begin(); arrayItr != jsonObject[sampleName].end(); ++arrayItr) {
        insArray -> push_back(*arrayItr);
        merArray -> push_back(*arrayItr);
        quickArray -> push_back(*arrayItr);
      }
      // Add the sample name to the CSV file line
      //theFile << itr.key() << ",";
      std::cout << itr.key() << ",";

      // insertion sort evaluation
      insStartTime = clock();
      insReturnArray = InsertionSort(insArray);
      insStartTime = clock() - insStartTime;
      insTime = ((float)insStartTime)/CLOCKS_PER_SEC;
      // Add the insertion sort data to the CSV file line
      //theFile << insTime << "," << *insReturnArray << "," << *(insReturnArray + 1) << "," ;
      std::cout << insTime << "," << *insReturnArray << "," << *(insReturnArray + 1) << ",";

      // merge sort evaluation
      merStartTime = clock();
      mergeReturnArray = MergeSort(merArray);
      merStartTime = clock() - merStartTime;
      merTime = ((float)merStartTime)/CLOCKS_PER_SEC;
      // Add the merge sort data to the CSV file line
      //theFile << merTime << "," << *mergeReturnArray << "," << *(mergeReturnArray + 1) << "," ;
      std::cout << merTime << "," << *mergeReturnArray << "," << *(mergeReturnArray + 1) << "," ;

      // quick sort evaluation
      quickStartTime = clock();
      quickReturnArray = QuickSort(quickArray);
      quickStartTime = clock() - quickStartTime;
      quickTime = ((float)quickStartTime)/CLOCKS_PER_SEC;
      // Add the quick sort data to the CSV file line
      //theFile << quickTime << "," << *quickReturnArray << "," << *(quickReturnArray + 1);
      //theFile << "\n";
      std::cout << quickTime << "," << *quickReturnArray << "," << *(quickReturnArray + 1) << std::endl;

      // clear the arrays for the next sample
      insArray -> clear();
      merArray -> clear();
      quickArray -> clear();
    }
  }

  //theFile.close();   // close CSV file
  file.close();      // close JSON file
  return 0;
}
