
// File: test_timsxicextractor.cpp
// Created by: Olivier Langella
// Created on: 3/2/2021
//
/*******************************************************************************
 * Copyright (c) 2021 Olivier Langella
 *<olivier.langella@universite-paris-saclay.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/>.
 *
 ******************************************************************************/

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

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


#include <catch2/catch_test_macros.hpp>
#include <catch2/benchmark/catch_benchmark.hpp>


#include <QDebug>

#include <pappsomspp/core/mzrange.h>
#include <pappsomspp/core/msfile/msfileaccessor.h>
#include <pappsomspp/core/msrun/private/timsmsrunreaderms2.h>
#include <pappsomspp/core/msrun/private/timsmsrunreader.h>
#include <pappsomspp/core/pappsoexception.h>
#include <pappsomspp/core/processing/filters/filtersuitestring.h>
#include <pappsomspp/core/xicextractor/msrunxicextractorfactory.h>
#include <pappsomspp/core/processing/uimonitor/uimonitortextpercent.h>
#include <pappsomspp/core/vendors/tims/timsddaprecursors.h>
#include "tests/tests-config.h"
#include "../common.h"
#include <time.h>


using namespace pappso;

TEST_CASE("Extracting XIC from timsdata", "[TimsXicExtractor]")
{
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));

#if USE_PAPPSO_TREE == 1

  QString file_path_name;
  /*
    file_path_name =
      "/gorgone/pappso/fichiers_fabricants/Bruker/tims_doc/tdf-sdk/"
      "example_data/"
      "200ngHeLaPASEF_2min_compressed.d/analysis.tdf";
  */

  // file_path_name =
  //"/home/rusconi/devel/dataForMzml/bruker/20210126_HeLa.d/"
  //"1-26-2021_1_QC_HeLa10ng_826.d/analysis.tdf";


  file_path_name =
    "/gorgone/pappso/jouy/raw/2021_Tims_TOF/20211124_HeLa/"
    "11-25-2021_1_HeLa200ng_2321.d/analysis.tdf";

  /*

  file_path_name =
    "/backup2/"
    "11-25-2021_1_HeLa200ng_2321.d/analysis.tdf";
*/
  // file_path_name =
  //"/home/rusconi/devel/dataForMzml/bruker/2021_Tims_TOF/20211124_HeLa/"
  //"11-25-2021_1_HeLa200ng_2321.d/analysis.tdf";

  qDebug() << "The file to use as a test base is: " << file_path_name;
  // When not in debug mode.
  std::cout << __FILE__ << ":" << __LINE__
            << " The file to use as a test base is: "
            << file_path_name.toStdString();

  pappso::MsFileAccessor accessor(file_path_name, "a1");


  accessor.setPreferredFileReaderType(Enums::MsDataFormat::brukerTims,
                                      Enums::FileReaderType::tims_ms2);
  WARN("get reader");
  pappso::MsRunReaderSPtr p_msreader =
    accessor.msRunReaderSPtr(accessor.getMsRunIds().front());
  WARN("get reader OK");

  REQUIRE(p_msreader != nullptr);

  REQUIRE(accessor.getFileReaderType() == Enums::FileReaderType::tims_ms2);

  pappso::TimsMsRunReaderMs2 *tims2_reader =
    dynamic_cast<pappso::TimsMsRunReaderMs2 *>(p_msreader.get());
  REQUIRE(tims2_reader != nullptr);


  pappso::TimsDataSp tims_data = tims2_reader->getTimsDataSPtr();

  std::vector<std::size_t> precursor_list = {2159};
  std::vector<pappso_double> mz_list      = {
         466.738, 467.239, 420, 421, 422, 423, 424, 425, 426};

  std::vector<pappso::XicCoordSPtr> xic_list;
  std::vector<pappso::XicCoordSPtr> xic_struct_list;

  clock_t start = clock();
  for(auto precursor_id : precursor_list)
    {
      xic_list.push_back(
        tims_data.get()
          ->getTimsDdaPrecursorsPtr()
          ->getXicCoordTimsFromPrecursorId(
            precursor_id, PrecisionFactory::getPpmInstance(30.0))
          .initializeAndClone());
    }

  for(pappso::pappso_double mz : mz_list)
    {
      pappso::XicCoordSPtr new_xic_struct =
        xic_list[0].get()->initializeAndClone();
      new_xic_struct.get()->mzRange =
        pappso::MzRange(mz, PrecisionFactory::getPpmInstance(30.0));
      xic_struct_list.push_back(new_xic_struct);
    }
  WARN("buildMsRunXicExtractorSp");
  MsRunXicExtractorInterfaceSp xic_extractor =
    MsRunXicExtractorFactory::getInstance().buildMsRunXicExtractorSp(
      p_msreader);

  WARN("buildMsRunXicExtractorSp OK");
  xic_extractor.get()->setXicExtractMethod(Enums::XicExtractMethod::sum);

  QTextStream outputStream(stdout, QIODevice::WriteOnly);
  UiMonitorTextPercent monitor(outputStream);
  WARN("monitor.setStatus");
  monitor.setStatus("Actually starting the XIC extraction.");
  WARN("extractXicCoordSPtrList start");
  xic_extractor.get()->extractXicCoordSPtrListParallelized(monitor,
                                                           xic_struct_list);
  WARN("extractXicCoordSPtrList stop");

  qInfo() << QString("Time taken: %1\n")
               .arg((double)(clock() - start) / CLOCKS_PER_SEC);
  for(auto &&xic_struct : xic_struct_list)
    {
      REQUIRE(xic_struct.get() != nullptr);
      QFile fileods(QString("%1/tims_xic_%2.ods")
                      .arg(CMAKE_BINARY_DIR)
                      .arg(xic_struct.get()->mzRange.getMz()));
      OdsDocWriter writer(&fileods);
      writer.writeLine();
      writer.writeCell("rtTarget");
      writer.writeCell(xic_struct.get()->rtTarget);
      writer.writeLine();
      XicOdsWriter xic_writer(writer);
      xic_writer.write(*xic_struct.get()->xicSptr.get());
      writer.close();
      fileods.close();
    }

#elif USEPAPPSOTREE == 1

  std::cout << std::endl << "..:: NO test TIMS TDF parsing ::.." << std::endl;

#endif
}
