#include <iostream>
#include <sstream>
//#include <mpi.h>
//#include <ctime>
//#include <executionblock.hpp>
#include "random.h"
#include "lattice3d.h"
//#include <fuser3d.h>

using namespace std;

template<typename T>
void get_from_command_line(int argc, char **argv, string name, T &a) {
    string value;
    for(int i=1; i<argc; ++i) {
        string argument(argv[i]);
        size_t found = argument.find(name);
        if(found!=string::npos) {
            size_t eqsgn = argument.find("=");
            value = string(argument,eqsgn+1,argument.size());
            break;
        }
    }
    stringstream vss(value);
    vss >> a;
}

int main(int argc, char **argv)
{
    // MPI_Init(NULL,NULL);
    // // Get the number of processes
    // int comm_size = 1;
    // MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
    // // Get the rank of the process
    // int comm_rank = 1;
    // MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
    // //time_t tzero = time(nullptr);
    // //cout << "tzero " << tzero << endl;

    uint64_t seed = 1;
    uint32_t steps = 2;
    char type = 'h';
    uint32_t nremove = 0;
    double weik = 4.0;
    uint32_t precr = 0;
    uint32_t niter = 1;
    uint32_t networks = 1;
    bool optional = true; //output data for individual realizations
    bool storeiv = true;
    get_from_command_line<>(argc,argv,"seed",seed);
    get_from_command_line<>(argc,argv,"steps",steps);
    get_from_command_line<>(argc,argv,"type",type);
    get_from_command_line<>(argc,argv,"nremove",nremove);
    get_from_command_line<double>(argc,argv,"weik",weik);
    get_from_command_line<>(argc,argv,"niter",niter);
    get_from_command_line<>(argc,argv,"networks",networks);
    get_from_command_line<>(argc,argv,"optional",optional);
    get_from_command_line<>(argc,argv,"storeiv",storeiv);
    get_from_command_line<>(argc,argv,"precr",precr);
    // seed = seed*1000ULL + comm_rank;

    cout << "seed = " << seed << endl;

    if(true) {
        Random ra(seed);
        int realizations = networks;
        //if(realizations>1) optional = false;
        for(int r=0; r<realizations; ++r) {
            Lattice lt(ra,steps,type,nremove,weik,precr);
            Lattice lb(ra,steps,'r',nremove,weik,0);
            Lattice l(ra,lb,lt);
            



            if(optional) {
                stringstream e_stream;
                e_stream << "edgelist_0_seed" << seed << "_" << r;
                l.export_edgelist_nobus(e_stream.str().c_str());
            }
            
            // Fuser f(l);
            // f.execute(niter);
            // if(storeiv) {
            //     stringstream namestream;
            //     namestream << "iv_seed" << seed << "_" << r;
            //     f.export_qstatic_iv_only_doubleprecision(namestream.str().c_str());
            // }
            // //stringstream p_stream;
            // //p_stream << "potentials_seed" << seed << "_" << r;
            // //f.export_potentials_nodewise(p_stream.str().c_str());
            // stringstream bs_stream;
            // bs_stream << "brokenlist_sorted_seed" << seed << "_" << r;
            // l.export_brokenlist_sorted_nobus(bs_stream.str().c_str());
        }
    }
    // //time_t tfinal = time(nullptr);
    // //time_t tdelta = tfinal-tzero;
    // //cout << "tfinal " << tfinal << "\n" <<
    // //    "tdelta " << tdelta << " s\n" <<
    // //    "nhours " << tdelta/3600 << endl;
    // MPI_Finalize();
}
