#include "bandit/bandit/bandit.h"
// BANDIT NEEDS TO BE INCLUDED FIRST!!!

#include "../../src/modules.h"
#include "../../src/process_int.h"
#include "../../src/cdo_options.h"
#include "test_module_list.h"
#include <iostream>
ProcessManager g_processManager;
void
cdoExit()
{
  g_processManager.killProcesses();
  exit(EXIT_FAILURE);
}

go_bandit([]() {

  cdo::progname = "cdo_bandit_test";
  cdo::setExitFunction(cdoExit);
  cdo::setContextFunction(processInqPrompt);

  bandit::describe("Process creation", []() {
    // inVariable_out0: child oper 2
    // inVariable_out1: child oper3 and oper4:
    // oper3: infile: 1
    // oper4: infile 2
    // outfile: filled by inVariable_out0
    std::vector<std::vector<const char *>> test_argvs
        = { { "-inVariable_out0", "in1", "in2" },
            { "-inVariable_out0", "in1" },
            { "-inVariable_out1", "in1", "in2", "ofile1" },
            { "-inVariable_out1", "in1", "ofile2" } };

    const int numberOfRuns = 4;
    unsigned int expectedInputForRun[numberOfRuns] = { 2, 1, 2, 1 };
    unsigned int expectedOutputs[numberOfRuns] = { 0, 0, 1, 1 };

    /*clang-format off*/
    //          Name     Func  Help   oper    mod    in
    //                                           num    out
    modules = {
        {"inVariable_out0",module_inVariable_out0},
        {"inVariable_out1",module_inVariable_out1}
    };
    registerOperatorsFromModules();
    /*clang-format on*/

    unsigned int i;
    for (i = 0; i < numberOfRuns; i++)
      {
        g_processManager.createProcessesFromInput(test_argvs[i].size(),
                                                  &test_argvs[i][0]);
        auto process = g_processManager.getProcess(0);
        std::string runInfo
            = std::string(g_processManager.getProcess(0).operatorName)
              + " in run " + std::to_string(i + 1);
        bandit::it("created inputs for:" + runInfo, [&]() {
          AssertThat(process.childProcesses.size()
                         + process.inputStreams.size(),
                     snowhouse::Equals(expectedInputForRun[i]));
        });
        bandit::it("created outputs for: " + runInfo, [&]() {
          AssertThat(process.parentProcesses.size()
                         + process.outputStreams.size(),
                     snowhouse::Equals(expectedOutputs[i]));
        });
        bandit::it("created right amount of processes", [&]() {
          AssertThat(1, snowhouse::Equals(g_processManager.processNums()));
        });
        g_processManager.clearProcesses();
      }
  });
});
int
main(int argc, char **argv)
{
  PROCESS_MANAGER=1;
  int result = bandit::run(argc, argv);

  return result;
}
