/** @file wave_simulation.cpp
 *
 *  @author Cory Alexander Balaton (coryab)
 *  @author Janita Ovidie Sandtrøen Willumsen (janitaws)
 *
 *  @version 1.0
 *
 *  @brief A program to generate wave simulation data
 *
 *  @bug No known bugs
 * */
#include "WaveSimulation.hpp"
#include "utils.hpp"

#include <fstream>
#include <string>

void execute_simulation(std::vector<std::string> &args)
{
    // Check that args has at least 11 elements
    if (args.size() < 11) {
        return;
    }

    WaveSimulation *sim;

    // This is a simulation without a barrier
    if (args.size() >= 11 && args.size() < 16) {
        sim = new WaveSimulation(
            std::stod(args[2]), std::stod(args[3]), std::stod(args[4]),
            std::stod(args[5]), std::stod(args[6]), std::stod(args[7]),
            std::stod(args[8]), std::stod(args[9]), std::stod(args[10]));
    }
    // This is a simulation with a barrier
    else if (args.size() >= 16) {
        sim = new WaveSimulation(
            std::stod(args[2]), std::stod(args[3]), std::stod(args[4]),
            std::stod(args[5]), std::stod(args[6]), std::stod(args[7]),
            std::stod(args[8]), std::stod(args[9]), std::stod(args[10]),
            std::stod(args[11]), std::stod(args[12]), std::stod(args[13]),
            std::stod(args[14]), std::stoi(args[15]));
    }

    // Execute a probability deviation simulation
    if (args[0].compare("deviation") == 0) {
        if (args.size() == 17) {
            sim->probability_deviation(args[1], args[16].compare("false"));
        }
        else if (args.size() == 12) {
            sim->probability_deviation(args[1], args[11].compare("false"));
        }
        else {
            sim->probability_deviation(args[1]);
        }
    }
    // Execute wave packet simulation
    else if (args[0].compare("simulate") == 0) {
        if (args.size() == 17) {
            sim->simulate(args[1], args[16].compare("false"));
        }
        else if (args.size() == 12) {
            sim->simulate(args[1], args[11].compare("false"));
        }
        else if (args.size() > 17) {
            std::vector<double> arr;
            for (size_t i = 16; i < args.size(); i++) {
                arr.push_back(std::stod(args[i]));
            }
            sim->simulate(args[1], arr);
        }
        else {
            sim->simulate(args[1]);
        }
    }
    delete sim;
}

int main(int argc, char **argv)
{
    // Check that an argument has been given
    if (argc < 2) {
        abort();
    }

    std::string filename = argv[1];

    std::ifstream infile;
    infile.open(filename);

    for (std::string line; std::getline(infile, line);) {
        std::vector<std::string> arr = utils::split(line, ';');
        execute_simulation(arr);
    }

    infile.close();
}
