#include <catch2/catch.hpp>

#include <QDebug>

#include <pappsomspp/processing/combiners/mzintegrationparams.h>


using namespace pappso;


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

  SECTION("Construct a MzIntegrationParams", "[MzIntegrationParams]")
  {
    MzIntegrationParams mz_integration_params1;
    PrecisionPtr precision_p = pappso::PrecisionFactory::getPpmInstance(20);

    REQUIRE(mz_integration_params1.getBinningType() == BinningType::NONE);

    REQUIRE(precision_p == mz_integration_params1.getPrecision());

    double smallestMz            = 1800.373856;
    double greatestMz            = 2600.956480;
    BinningType binningType      = BinningType::ARBITRARY;
    int decimalPlaces            = 3;
    bool applyMzShift            = false;
    double mzShift               = 0;
    bool removeZeroValDataPoints = true;


    MzIntegrationParams mz_integration_params2(smallestMz,
                                               greatestMz,
                                               binningType,
                                               decimalPlaces,
                                               precision_p,
                                               applyMzShift,
                                               mzShift,
                                               removeZeroValDataPoints);

    REQUIRE(mz_integration_params2.getSmallestMz() == smallestMz);
    REQUIRE(mz_integration_params2.getGreatestMz() == greatestMz);
    REQUIRE(mz_integration_params2.getBinningType() == binningType);
    REQUIRE(mz_integration_params2.getDecimalPlaces() == decimalPlaces);
    REQUIRE(mz_integration_params2.getPrecision() == precision_p);
    REQUIRE(mz_integration_params2.isApplyMzShift() == applyMzShift);
    REQUIRE(mz_integration_params2.getMzShift() == mzShift);
    REQUIRE(mz_integration_params2.isRemoveZeroValDataPoints() ==
            removeZeroValDataPoints);
  }


  SECTION(
    "Construct a MzIntegrationParams from another "
    "MzIntegrationParams",
    "[MzIntegrationParams]")
  {

    double smallestMz            = 1800.373856;
    double greatestMz            = 2600.956480;
    BinningType binningType      = BinningType::ARBITRARY;
    int decimalPlaces            = 3;
    PrecisionPtr precision_p     = pappso::PrecisionFactory::getPpmInstance(20);
    bool applyMzShift            = false;
    double mzShift               = 0;
    bool removeZeroValDataPoints = true;

    MzIntegrationParams mz_integration_params1(smallestMz,
                                               greatestMz,
                                               binningType,
                                               decimalPlaces,
                                               precision_p,
                                               applyMzShift,
                                               mzShift,
                                               removeZeroValDataPoints);

    MzIntegrationParams mz_integration_params2(mz_integration_params1);

    REQUIRE(mz_integration_params2.getSmallestMz() == smallestMz);
    REQUIRE(mz_integration_params2.getGreatestMz() == greatestMz);
    REQUIRE(mz_integration_params2.getBinningType() == binningType);
    REQUIRE(mz_integration_params2.getDecimalPlaces() == decimalPlaces);
    REQUIRE(mz_integration_params2.getPrecision() == precision_p);
    REQUIRE(mz_integration_params2.isApplyMzShift() == applyMzShift);
    REQUIRE(mz_integration_params2.getMzShift() == mzShift);
    REQUIRE(mz_integration_params2.isRemoveZeroValDataPoints() ==
            removeZeroValDataPoints);
  }
}

TEST_CASE("Create bins", "[MzIntegrationParams]")
{
  double smallestMz       = 1800.373856;
  double greatestMz       = 2600.956480;
  BinningType binningType = BinningType::ARBITRARY;
  int decimalPlaces       = 3;
  // PrecisionPtr precision_p     =
  // pappso::PrecisionFactory::getPpmInstance(20);
  PrecisionPtr precision_p     = pappso::PrecisionFactory::getPpmInstance(2000);
  bool applyMzShift            = false;
  double mzShift               = 0;
  bool removeZeroValDataPoints = true;

  MzIntegrationParams mz_integration_params(smallestMz,
                                            greatestMz,
                                            binningType,
                                            decimalPlaces,
                                            precision_p,
                                            applyMzShift,
                                            mzShift,
                                            removeZeroValDataPoints);

  SECTION("Create bins in ARBITRARY mode", "[MzIntegrationParams]")
  {

    std::vector<double> bins = mz_integration_params.createBins();

    // Do not forget that we round to 3 decimal places:
    REQUIRE(bins.front() == 1800.374);
    REQUIRE(bins.back() == 2605.505);
  }
}
