//
// File: test_xtandem_spectrum.cpp
// Created by: Olivier Langella
// Created on: 13/3/2015
//
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     PAPPSOms++ is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

// ./tests/catch2-only-tests [xtandemspectrum] -s


#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp>

#include <pappsomspp/core/mzrange.h>
#include <pappsomspp/core/peptide/peptidenaturalisotopelist.h>
#include <pappsomspp/core/peptide/peptidefragmentionlistbase.h>
#include <pappsomspp/core/massspectrum/massspectrum.h>
#include <pappsomspp/core/psm/xtandem/xtandemspectrumprocess.h>
#include <pappsomspp/core/processing/filters/filterpass.h>
#include <iostream>
#include <set>
#include <QDir>
#include <QDebug>
#include <QString>
#include "tests/tests-config.h"
#include "common.h"

using namespace pappso;
using namespace std;
// using namespace pwiz::msdata;

// make test ARGS="-V -I 16,16"

TEST_CASE("Xtandem spectrum test suite.", "[xtandemspectrum]")
{
  // Set the debugging message formatting pattern.
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));

  SECTION("..:: readMgf ::..", "[xtandemspectrum]")
  {
    std::cout << std::endl
              << "..:: readMgf ::.." << QDir::currentPath().toStdString()
              << std::endl;

    MassSpectrum spectrum = readMgf(
      QString(CMAKE_SOURCE_DIR).append("/tests/data/peaklist_15046.mgf"));

    std::cout << spectrum.toString().toStdString() << std::endl;
    MassSpectrum spectrum_orig(spectrum);
    REQUIRE(spectrum.equals(spectrum_orig,
                            PrecisionFactory::getDaltonInstance(0.00002)));
    // spectrum =
    // spectrum.applyCutOff(150).takeNmostIntense(100).applyDynamicRange(100).round();


    MassSpectrum spectrum_b = readMgf(
      QString(CMAKE_SOURCE_DIR).append("/tests/data/peaklist_15046.mgf"));
    REQUIRE(spectrum == spectrum_b);


    MassSpectrum spectrum_simple =
      readMgf(QString(CMAKE_SOURCE_DIR)
                .append("/tests/data/peaklist_15046_simple_xt.mgf"))
        .massSpectrumFilter(MassSpectrumFilterGreatestItensities(7));

    REQUIRE_FALSE(spectrum == spectrum_simple);
    std::vector<double> expected_mass_list(
      {157.133, 175.119, 185.128, 308.188, 401.287, 886.535, 1072.6});
    REQUIRE_THAT(spectrum_simple.xValues(),
                 Catch::Matchers::Approx(expected_mass_list));
    std::vector<double> expected_intensity_list(
      {100.0, 30.0, 42.0, 33.0, 27.0, 19.0, 21.0});
    REQUIRE_THAT(spectrum_simple.yValues(),
                 Catch::Matchers::Approx(expected_intensity_list));
    // mh="1256.7213" z=2 AIADGSLLDLLR
    Peptide peptide("AIADGSLLDLLR");
    INFO("spectrum.removeParent");

    XtandemSpectrumProcess xt_spectrum_process;
    xt_spectrum_process.setExcludeParent(true);
    xt_spectrum_process.setNmostIntense(7);
    xt_spectrum_process.setDynamicRange(100);
    xt_spectrum_process.setMinimumMz(150);
    // MassRange neutral_loss_mass =
    // xt_spectrum_process.getNeutralLossMassRange(peptide, 2);

    // spectrum=
    // spectrum.removeMassRange(neutral_loss_mass).applyCutOff(150).takeNmostIntense(7).applyDynamicRange(100).round();
    spectrum = xt_spectrum_process.process(spectrum, 628.86414, 2);
    FilterRoundY().filter(spectrum);
    REQUIRE(peptide.makePeptideSp().get()->getMz(2) ==
            Catch::Approx(628.8640771426));
    spectrum.debugPrintValues();
    spectrum_simple.debugPrintValues();
    REQUIRE(spectrum.equals(spectrum_simple,
                            PrecisionFactory::getDaltonInstance(0.02)));
  }
}
