
#include <catch2/catch_test_macros.hpp>


#include <QDebug>

#include <pappsomspp/trace/datapoint.h>
#include <pappsomspp/trace/trace.h>
#include <pappsomspp/trace/maptrace.h>
#include <pappsomspp/massspectrum/massspectrum.h>
#include <pappsomspp/processing/combiners/massdatacombinerinterface.h>
#include <pappsomspp/processing/combiners/tracepluscombiner.h>


using namespace pappso;


TEST_CASE("Constructing TracePlusCombiner objects.",
          "[TracePlusCombiner][constructors]")
{

  SECTION("Construct a TracePlusCombiner", "[TracePlusCombiner]")
  {
    int decimal_places = 3;
    TracePlusCombiner trace_combiner(decimal_places);

    REQUIRE(trace_combiner.getDecimalPlaces() == decimal_places);
  }

  SECTION("Construct a TracePlusCombiner from another TracePlusCombiner",
          "[TracePlusCombiner]")
  {
    int decimal_places = 3;
    TracePlusCombiner trace_combiner(decimal_places);
    TracePlusCombiner trace_combiner1(trace_combiner);

    REQUIRE(trace_combiner1.getDecimalPlaces() == decimal_places);
  }
}

TEST_CASE("Performing combinations with TracePlusCombiner",
          "[TracePlusCombiner][combinations]")
{
  // Create two different traces.

  std::vector<DataPoint> data_point_vector1;

  // clang-format off
  data_point_vector1.push_back(DataPoint("610.02000 12963.5715942383"));
  data_point_vector1.push_back(DataPoint("610.07000 15639.6568298340"));
  data_point_vector1.push_back(DataPoint("610.12000 55999.7628784180"));
  data_point_vector1.push_back(DataPoint("610.17000 9335990.3578681946"));
  data_point_vector1.push_back(DataPoint("610.2200000 635674266.1611375809"));
  data_point_vector1.push_back(DataPoint("610.27000 54459.4762458801"));
  data_point_vector1.push_back(DataPoint("610.32000 205580.6580276489"));
  data_point_vector1.push_back(DataPoint("610.37000 84627.3196716309"));
  data_point_vector1.push_back(DataPoint("610.42000 51061.7636718750"));
  data_point_vector1.push_back(DataPoint("610.47000 20260.0218505859"));
  // clang-format on

  Trace trace1(data_point_vector1);

  std::vector<DataPoint> data_point_vector2;

  // clang-format off
  data_point_vector2.push_back(DataPoint("610.02000 22963.5725942383"));
  data_point_vector2.push_back(DataPoint("620.04000 22963.5725942383"));
  data_point_vector2.push_back(DataPoint("620.07000 25639.6568298340"));
  data_point_vector2.push_back(DataPoint("620.25000 55999.7628784280"));
  data_point_vector2.push_back(DataPoint("620.30000 205580.6580276489"));
  data_point_vector2.push_back(DataPoint("620.35000 84627.3296726309"));
  data_point_vector2.push_back(DataPoint("620.40000 52062.7636728750"));
  data_point_vector2.push_back(DataPoint("620.45000 20260.0228505859"));
  // clang-format on

  Trace trace2(data_point_vector2);

  SECTION("Combine two Trace into a MapTrace.", "[TracePlusCombiner]")
  {
    MapTrace map_trace;

    int decimal_places = 3;
    TracePlusCombiner combiner(decimal_places);

    combiner.combine(map_trace, trace1);
    REQUIRE(map_trace.size() == 10);

    combiner.combine(map_trace, trace2);
    REQUIRE(map_trace.size() == 17);

    // There was that 610.02000 m/z point in both traces, so
    // combination needs to add up the intensities.
    REQUIRE(map_trace[610.02000] == 12963.5715942383 + 22963.5725942383);
  }


  SECTION("Combine two MapTrace into a MapTrace.", "[TracePlusCombiner]")
  {
    MapTrace map_trace;

    int decimal_places = 3;
    TracePlusCombiner combiner(decimal_places);

    MapTrace map_trace1(trace1);
    MapTrace map_trace2(trace2);

    combiner.combine(map_trace, map_trace1);
    REQUIRE(map_trace.size() == 10);

    combiner.combine(map_trace, map_trace2);
    REQUIRE(map_trace.size() == 17);

    // There was that 610.02000 m/z point in both traces, so
    // combination needs to add up the intensities.
    REQUIRE(map_trace[610.02000] == 12963.5715942383 + 22963.5725942383);
  }
}
