/** @file time.cpp
 *
 *  @author Cory Alexander Balaton (coryab)
 *  @author Janita Ovidie Sandtrøen Willumsen (janitaws)
 *
 *  @version 0.1
 *
 *  @brief Timing various things
 *
 *  @bug No known bugs
 * */
#include "data_type.hpp"
#include "monte_carlo.hpp"
#include "utils.hpp"

#include <getopt.h>
#include <omp.h>
#include <ostream>

void time_lattice_sizes()
{
    std::string outfile = "output/timing/lattice_sizes.txt";
    std::ofstream ofile;

    int lattice_sizes[] = {20, 40, 60, 80, 100};

    utils::mkpath(utils::dirname(outfile));
    ofile.open(outfile);
    double t0, t1;
    for (int L : lattice_sizes) {
        t0 = omp_get_wtime();
        montecarlo::phase_transition(L, 2.1, 2.4, 40, 100000,
                                     montecarlo::mcmc_parallel, "/dev/null");
        t1 = omp_get_wtime();
        ofile << utils::scientific_format(L) << ','
              << utils::scientific_format(t1 - t0) << '\n';
    }
    ofile.close();
}

void time_sample_sizes()
{
    std::string outfile = "output/timing/sample_sizes.txt";
    std::ofstream ofile;

    int sample_sizes[] = {1000, 10000, 100000};

    utils::mkpath(utils::dirname(outfile));
    ofile.open(outfile);
    double t0, t1;
    for (int samples : sample_sizes) {
        t0 = omp_get_wtime();
        montecarlo::phase_transition(20, 2.1, 2.4, 40, samples,
                                     montecarlo::mcmc_parallel, "/dev/null");
        t1 = omp_get_wtime();
        ofile << utils::scientific_format(samples) << ','
              << utils::scientific_format(t1 - t0) << '\n';
    }
    ofile.close();
}

void usage(std::string filename)
{
    std::cout << "Usage: " << filename << " OPTION ...\n"
              << "At least one option should be used.\n\n"
              << "\t[ -h | --help ]\n"
              << "\t[ --all ]\n"
              << "\t[ --time-lattice-sizes ]\n"
              << "\t[ --time-sample-sizes ]\n";
    exit(-1);
}

int main(int argc, char **argv)
{
    struct option long_options[] = {{"all", 0, 0, 0},
                                    {"time-lattice-sizes", 0, 0, 0},
                                    {"time-sample-sizes", 0, 0, 0},
                                    {"help", 0, 0, 0},
                                    {NULL, 0, NULL, 0}};

    int option_index = -1;
    int c;

    while (true) {
        c = getopt_long(argc, argv, "h", long_options, &option_index);

        if (c == -1)
            break;

        switch (c) {
        case 0:
            switch (option_index) {
            case 0:
                time_lattice_sizes();
                time_sample_sizes();
                break;
            case 1:
                time_lattice_sizes();
                break;
            case 2:
                time_sample_sizes();
                break;
            case 3: // Not a mistake. This just goes to the default.
            default:
                usage(argv[0]);
            }
            break;
        case 'h':
        default:
            usage(argv[0]);
        }
    }

    return 0;
}
