/**
 * \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()
{
  msp_timsData = nullptr;
}

void
TimsMsRunReader::initialize()
{
  msp_timsData = std::make_shared<TimsData>(mcsp_msRunId.get()->getFileName());
  if(msp_timsData == nullptr)
    {
      throw PappsoException(QObject::tr("ERROR in TimsMsRunReader::initialize "
                                        "msp_timsData is null for MsRunId %1")
                              .arg(mcsp_msRunId.get()->toString()));
    }
}


bool
TimsMsRunReader::accept(const QString &file_name) const
{
  qDebug() << 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 msp_timsData->getMassSpectrumCstSPtrByRawIndex(spectrum_index);
}


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

  QualifiedMassSpectrum mass_spectrum;

  msp_timsData->getQualifiedMassSpectrumByRawIndex(
    getMsRunId(), mass_spectrum, spectrum_index, want_binary_data);
  return mass_spectrum;
}


void
TimsMsRunReader::readSpectrumCollection(
  SpectrumCollectionHandlerInterface &handler)
{
  readSpectrumCollectionByMsLevel(handler, 0);
}


void
TimsMsRunReader::readSpectrumCollectionByMsLevel(
  SpectrumCollectionHandlerInterface &handler, unsigned int ms_level)
{

  qDebug();


  msp_timsData.get()->rawReaderSpectrumCollectionByMsLevel(
    getMsRunId(), handler, ms_level);

  // 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 msp_timsData->getTotalNumberOfScans();
}


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


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

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


XicCoordSPtr
TimsMsRunReader::newXicCoordSPtrFromSpectrumIndex(std::size_t spectrum_index
                                                  [[maybe_unused]],
                                                  pappso::PrecisionPtr precision
                                                  [[maybe_unused]]) const
{
  throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
                                  .arg(__FILE__)
                                  .arg(__FUNCTION__)
                                  .arg(__LINE__));
}

XicCoordSPtr
TimsMsRunReader::newXicCoordSPtrFromQualifiedMassSpectrum(
  const pappso::QualifiedMassSpectrum &mass_spectrum [[maybe_unused]],
  pappso::PrecisionPtr precision [[maybe_unused]]) const
{
  throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
                                  .arg(__FILE__)
                                  .arg(__FUNCTION__)
                                  .arg(__LINE__));
}

TimsDataSp
TimsMsRunReader::getTimsDataSPtr()
{
  acquireDevice();
  return msp_timsData;
}


Trace
TimsMsRunReader::getTicChromatogram()
{
  // Use the Sqlite database to fetch the total ion current chromatogram (TIC
  // chromatogram).

  acquireDevice();

  return msp_timsData->getTicChromatogram();
}

