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

#include "json.hpp"

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;
  }

  std::string sampleName;     // Sample key name to iterate
  nlohmann::json outputJSON;  // output JSON file
  int numberInversions = 0;   // total number of samples with inversions
  int currValue = 0;          // current element value
  int prevValue = 0;          // previous element value

  // iterate through samples
  for (auto itr = jsonObject.begin(); itr != jsonObject.end(); ++itr) {
    sampleName = itr.key();
    int loopCounter = 0;       // counter to figure out array's element number
    int inversionCounter = 0;  // counts the number of consecutive inversions per sample

    if (sampleName != "metadata") {
      for (auto arrayItr = jsonObject[sampleName].begin(); arrayItr != jsonObject[sampleName].end(); ++arrayItr) {
        nlohmann::json inversion; // if there is a consecutive inversion

        // on the first iteration of the loop it saves the first element number
        if (loopCounter == 0) {
          currValue = *arrayItr;
          loopCounter++;

        } else { // after the first loop iteration, the program has both the current and previous values so it can start comparing them
          prevValue = currValue;
          currValue = *arrayItr;
          loopCounter++;

          if (currValue < prevValue) {
            // add the two values in the consecutive inversion to a JSON array
            inversion.push_back(prevValue);
            inversion.push_back(currValue);

            // convert loopCounter into a string to use it as a key name in JSON object
            std::stringstream convert2String;
            convert2String << (loopCounter-2); // loopCounter is two numbers ahead of the actual array element value
            // because (a) the loop starts at 1 and the elements at zero
            // and (b) the loop is comparing backwards so it is one element ahead of the one that has the consecutive inversion
            std::string arrayElementNumber = convert2String.str();
            outputJSON[sampleName]["ConsecutiveInversions"][arrayElementNumber] = inversion;

            inversionCounter++; // adds one every time a consecutive inversion is detected

            // at 1st inversion
            if (inversionCounter == 1) {
              outputJSON[sampleName]["sample"] = itr.value();
              numberInversions++;
            }
          }
        }
      }
    }
  }
  // create metadata key values
  outputJSON["metadata"]["arraySize"] = jsonObject["metadata"]["arraySize"];
  outputJSON["metadata"]["file"] = argv[1];
  outputJSON["metadata"]["numSamples"] = jsonObject["metadata"]["numSamples"];
  outputJSON["metadata"]["samplesWithInversions"] = numberInversions;

  // JSON output
  std::cout << outputJSON << std::endl;
  file.close();
}
