//===-- examples/CSVFiles/main.cpp --------------------------------*- C++ -*-===//
//
//                 The RoSA Framework -- Example CSVFiles
//
//===----------------------------------------------------------------------===//
///
/// \file  examples/CSVFiles/main.cpp
///
/// \author Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief This example shows how you could use the CSVIterator class to 
/// get data into RoSA from a CSV-file.
//===----------------------------------------------------------------------===//


// To compile with dumping record layout:
// $ clang++ -o variadic-tuple -Xclang -fdump-record-layouts variadic-tuple.cpp
//           -Wall -g -std=c++11
#include <cstdint>
#include <cstddef>
#include <iostream>
#include <istream>
#include <sstream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>
#include <typeinfo>
#include <map>
#include <algorithm>
#include <tuple>
#include <type_traits>
#include <unistd.h>

#include "rosa/support/csv/CSVReader.hpp"

const std::string AppName = "test-csvfiles";

//the example will be executed in the bin directory, but the data files are located in another the examples folder

const std::string Path = "../examples/CSVFiles/";

void testtuple(){

   //Different stream objects to work on CSV data and show the limitations of the current implementation. 
   //If you don't find any of these files, just create your own data files.
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data(Path + "HR-New.csv");
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data_2(Path + "HR-New.csv");
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data_3(Path + "HR-New.csv");
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data_4(Path + "HR-New.csv");
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data_5(Path + "HR-New.csv");
   //file contains header and valid data entries, delimter = ','
   std::ifstream file_header_data_6(Path + "HR-New.csv");
   //file contains no header an valid data entries, delimter = ','
   std::ifstream file2(Path + "HR.csv");
   //file contains header and valid data entries, delimter = ';'
   std::ifstream file3(Path + "HR-New-Semicolon.csv");

   rosa::csv::CSVIterator<int, std::string, std::string, int, int> it(file_header_data);

   it.setDelimeter(',');

   it++;
   it++;
   //if you iterate over the end of file, the last values
   //of the file will remain in the data structure but no
   //error occurs.
   it++;
   it++;

   //-------------------------------------------------------------------
   // a possiblity to get the data out of the iterator
   std::tuple<int, std::string, std::string, int, int> value =  *it;

   std::cout << "Values are: " << std::get<0>(value) << " "
             << std::get<1>(value) << " ,are you now happy?" << std::endl;


   //--------------------------------------------------------------------
   //testing differnet parameters to the constructor

   //uncomment to see that it is not possible to iterate over an vector in the tuple.
   //rosa::csv::CSVIterator<double, std::vector<int>> it2(file, 1);

   //try to skip a valid number of lines after the header
   rosa::csv::CSVIterator<double, float, int, int, float> it2_0(file_header_data_2, 1);
   //try to skip a valid number of lines after the header, but you assume that the file has no header
   //uncomment this line to crash the programm
   //rosa::csv::CSVIterator<double, float, int, int, float> it2_1(file_header_data_3, 0, rosa::csv::HeaderInformation::HasNoHeader);

   //try to skip a valid number of lines after the header, but you assume that the file has no header
   //uncomment this line to crash the program
  // rosa::csv::CSVIterator<double, float, int, int, float> it2_2(file_header_data_4, 1, rosa::csv::HeaderInformation::HasNoHeader);

   //try to skip a valid number of lines of a file without header
   rosa::csv::CSVIterator<double, float, int, int, float> it2_3(file2, 1, rosa::csv::HeaderInformation::HasNoHeader);

   //try to skip a valid number of lines after the header, but with different delimeter
   rosa::csv::CSVIterator<double, float, int, int, float> it2_4(file3, 2,rosa::csv::HeaderInformation::HasHeader, ';');

   // if you skip more lines than valid, you generate an infinte loop
   //rosa::csv::CSVIterator<double, float, int, int, float> it3(file_header_data_5, 500);

   //if you don't need data from all columns just select the number of columns you
   //need. You get the data back from the first column (index 0) to the fourth column
   //all values from the fifth column are ignored.
   rosa::csv::CSVIterator<double, float, int, float> it4(file_header_data_6);
}

int main(void) {
  std::cout << "This is a short example to show you how you could use the CSVIterator class." << std::endl;
  std::cout << "There are also some limitations explained in the source code of the example." << std::endl;  

  testtuple();

  std::cout << "All tests finished sucessfully" << std::endl;
  return 0;
}

