/**
 * \file pappsomspp/msrun/private/timsmsrunreader.h
 * \date 05/09/2019
 * \author Olivier Langella
 * \brief MSrun file reader for native Bruker TimsTOF raw data
 */

/*******************************************************************************
 * Copyright (c) 2019 Olivier Langella <Olivier.Langella@u-psud.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/>.
 *
 ******************************************************************************/

#include "timsmsrunreader.h"
#include "../../exception/exceptionnotimplemented.h"
#include <QDebug>

using namespace pappso;

TimsMsRunReader::TimsMsRunReader(MsRunIdCstSPtr &msrun_id_csp)
  : MsRunReader(msrun_id_csp)
{
  initialize();
}

TimsMsRunReader::~TimsMsRunReader()
{
  if(mpa_timsData != nullptr)
    {
      delete mpa_timsData;
    }
}

void
pappso::TimsMsRunReader::initialize()
{
  mpa_timsData = new TimsData(mcsp_msRunId.get()->getFileName());
}


bool
TimsMsRunReader::accept(const QString &file_name) const
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
           << file_name;
  return true;
}


pappso::MassSpectrumSPtr
TimsMsRunReader::massSpectrumSPtr([[maybe_unused]] std::size_t spectrum_index)
{
  throw ExceptionNotImplemented(
    QObject::tr("Not yet implemented in TimsMsRunReader %1.\n").arg(__LINE__));
  return pappso::MassSpectrumSPtr();
}


pappso::MassSpectrumCstSPtr
TimsMsRunReader::massSpectrumCstSPtr(std::size_t spectrum_index)
{
  return mpa_timsData->getMassSpectrumCstSPtrByRawIndex(spectrum_index);
}


QualifiedMassSpectrum
TimsMsRunReader::qualifiedMassSpectrum(std::size_t spectrum_index,
                                       bool want_binary_data) const
{

  QualifiedMassSpectrum mass_spectrum =
    mpa_timsData->getQualifiedMassSpectrumByRawIndex(spectrum_index,
                                                     want_binary_data);

  MassSpectrumId spectrum_id(mass_spectrum.getMassSpectrumId());
  spectrum_id.setMsRunId(getMsRunId());
  mass_spectrum.setMassSpectrumId(spectrum_id);
  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
  //<< mass_spectrum.toString();

  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
  //<< mass_spectrum.getMassSpectrumSPtr().get()->toString();
  return mass_spectrum;
}


void
TimsMsRunReader::readSpectrumCollection(
  SpectrumCollectionHandlerInterface &handler)
{
  qDebug();

  const bool want_binary_data = handler.needPeakList();

  // We'll need it to perform the looping in the spectrum list.
  std::size_t spectrum_list_size = spectrumListSize();

  qDebug() << "The spectrum list has size:" << spectrum_list_size;

  // Inform the handler of the spectrum list so that it can handle feedback to
  // the user.
  handler.spectrumListHasSize(spectrum_list_size);

  // Iterate in the full list of spectra.
  // mpa_timsData->iterateOnAllScans(mcsp_msRunId, handler);

  for(std::size_t iter = 0; iter < spectrum_list_size; iter++)
    {

      // If the user of this reader instance wants to stop reading the spectra,
      // then break this loop.
      if(handler.shouldStop())
        {
          qDebug() << "The operation was cancelled. Breaking the loop.";
          break;
        }


      bool get_data = want_binary_data;
      if(get_data)
        {
          get_data = handler.needMsLevelPeakList(
            mpa_timsData->getMsLevelBySpectrumIndex(iter));
        }
      qDebug();

      QualifiedMassSpectrum qualified_mass_spectrum =
        qualifiedMassSpectrum(iter, get_data);
      qDebug();
      handler.setQualifiedMassSpectrum(qualified_mass_spectrum);
      qDebug();
    }
  // End of
  // for(std::size_t iter = 0; iter < spectrum_list_size; iter++)

  // Now let the loading handler know that the loading of the data has ended.
  // The handler might need this "signal" to perform additional tasks or to
  // cleanup cruft.

  // qDebug() << "Loading ended";
  handler.loadingEnded();
}


std::size_t
TimsMsRunReader::spectrumListSize() const
{
  return mpa_timsData->getTotalNumberOfScans();
}


bool
TimsMsRunReader::hasScanNumbers() const
{
  return false;
}


bool
TimsMsRunReader::releaseDevice()
{
  delete mpa_timsData;
  mpa_timsData = nullptr;
  return true;
}

bool
TimsMsRunReader::acquireDevice()
{
  if(mpa_timsData == nullptr)
    {
      initialize();
    }
  return true;
}
