/**
 * \file pappsomspp/core/msrun/spectrumcollectionhandlerinterface.h
 * \date 29/05/2018
 * \author Olivier Langella
 * \brief base interface to read MSrun files
 */

/*******************************************************************************
 * Copyright (c) 2018 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 <QDebug>
#include <QObject>

#include "pappsomspp/core/exception/exceptionnotfound.h"
#include "spectrumcollectionhandlerinterface.h"

namespace pappso
{

bool
SpectrumCollectionHandlerInterface::shouldStop()
{
  return false;
}
void
SpectrumCollectionHandlerInterface::loadingEnded()
{
}
void
SpectrumCollectionHandlerInterface::spectrumListHasSize([[maybe_unused]] std::size_t size)
{
}
void
SpectrumCollectionHandlerInterface::setReadAhead(bool is_read_ahead)
{
  m_isReadAhead = is_read_ahead;
}

bool
SpectrumCollectionHandlerInterface::isReadAhead() const
{
  return m_isReadAhead;
}

bool
SpectrumCollectionHandlerInterface::needMsLevelPeakList(unsigned int ms_level) const
{
  if(needPeakList() == true)
    {
      if(ms_level < m_needPeakListByMsLevel.size())
        {
          return m_needPeakListByMsLevel[ms_level];
        }
      else
        return true;
    }
  else
    {
      return false;
    }
}
void
SpectrumCollectionHandlerInterface::setNeedMsLevelPeakList(unsigned int ms_level,
                                                           bool want_peak_list)
{
  if(ms_level < m_needPeakListByMsLevel.size())
    {
      m_needPeakListByMsLevel[ms_level] = want_peak_list;
    }
}

bool
MsRunSimpleStatistics::needPeakList() const
{
  return false;
}


void
MsRunSimpleStatistics::loadingEnded()
{
  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
  //<< "The data loading process ended.";
}


void
MsRunSimpleStatistics::setQualifiedMassSpectrum(const QualifiedMassSpectrum &qspectrum)
{
  // The vector[0] contains the number of spectra at MS
  // The vector[1] contains the number of spectra at MS^2
  // The vector[2] contains the number of spectra at MS^3
  // ...

  unsigned int ms_level = qspectrum.getMsLevel();
  if(ms_level == 0)
    return;
  if(ms_level > m_countMsLevelSpectrum.size())
    {
      m_countMsLevelSpectrum.resize(ms_level);
    }
  m_countMsLevelSpectrum[ms_level - 1]++;
}


unsigned long
MsRunSimpleStatistics::getMsLevelCount(unsigned int ms_level) const
{
  if(ms_level == 0)
    return 0;
  if(ms_level > m_countMsLevelSpectrum.size())
    return 0;
  return (m_countMsLevelSpectrum[ms_level - 1]);
}


unsigned long
MsRunSimpleStatistics::getTotalCount() const
{
  unsigned long total = 0;
  for(unsigned long count : m_countMsLevelSpectrum)
    {
      total += count;
    }
  return total;
}


MsRunReaderScanNumberMultiMap::MsRunReaderScanNumberMultiMap()
{
  // qDebug();
}


MsRunReaderScanNumberMultiMap::~MsRunReaderScanNumberMultiMap()
{
  // qDebug();
}


bool
MsRunReaderScanNumberMultiMap::needPeakList() const
{
  return false;
}

void
MsRunReaderScanNumberMultiMap::setQualifiedMassSpectrum(const QualifiedMassSpectrum &qspectrum)
{
  qDebug() << " " << qspectrum.getMassSpectrumId().getNativeId();

  QStringList native_id_list = qspectrum.getMassSpectrumId().getNativeId().split("=");
  if(native_id_list.size() < 2)
    {
      return;
    }
  else
    {
      std::size_t scan_number = native_id_list.back().toULong();
      m_mmap_scan2index.insert(std::pair<std::size_t, std::size_t>(
        scan_number, qspectrum.getMassSpectrumId().getSpectrumIndex()));

      qDebug() << "scan number " << scan_number << "=>"
               << qspectrum.getMassSpectrumId().getSpectrumIndex();
    }
}

std::size_t
MsRunReaderScanNumberMultiMap::getSpectrumIndexFromScanNumber(std::size_t scan_number) const
{

  qDebug() << m_mmap_scan2index.size();

  auto it = m_mmap_scan2index.find(scan_number);

  if(it == m_mmap_scan2index.end())
    {
      throw ExceptionNotFound(QObject::tr("scan number %1 not found").arg(scan_number));
    }

  std::size_t index = it->second;

  it++;
  if((it != m_mmap_scan2index.end()) && (it->first == scan_number))
    {
      throw PappsoException(QObject::tr("scan number %1 found multiple times").arg(scan_number));
    }
  return index;
}


MsRunReaderRetentionTimeLine::MsRunReaderRetentionTimeLine()
{
  // qDebug();
}


MsRunReaderRetentionTimeLine::~MsRunReaderRetentionTimeLine()
{
  // qDebug();
}


bool
MsRunReaderRetentionTimeLine::needPeakList() const
{
  return false;
}


void
MsRunReaderRetentionTimeLine::setQualifiedMassSpectrum(const QualifiedMassSpectrum &qspectrum)
{
  qDebug() << " " << qspectrum.getMassSpectrumId().getNativeId();

  m_retention_time_list.push_back(qspectrum.getRtInSeconds());
}

const std::vector<double> &
MsRunReaderRetentionTimeLine::getRetentionTimeLine() const
{
  return m_retention_time_list;
}

MsRunReaderTicChromatogram::MsRunReaderTicChromatogram()
{
}


MsRunReaderTicChromatogram::~MsRunReaderTicChromatogram()
{
}


bool
MsRunReaderTicChromatogram::needPeakList() const
{
  return true;
}


void
MsRunReaderTicChromatogram::setQualifiedMassSpectrum(
  const QualifiedMassSpectrum &qualified_mass_spectrum)
{
  // In this specialized reader we want to compute the total ion current
  // chromatogram that plot the sum of all the ion intensities in the spectra as
  // a function of the retention time.

  uint spectrum_ms_level = qualified_mass_spectrum.getMsLevel();

  if(spectrum_ms_level != 1)
    return;

  double sumY = qualified_mass_spectrum.getMassSpectrumSPtr()->sumY();

  if(!sumY)
    return;

  double rt = qualified_mass_spectrum.getRtInMinutes();

  m_ticChromTrace.push_back({rt, sumY});
  /*
  using Pair     = std::pair<double, double>;
  using Map      = std::map<double, double>;
  using Iterator = Map::iterator;

  std::pair<Iterator, bool> res = m_ticChromMapTrace.insert(Pair(rt, sumY));

  if(!res.second)
    {
      // One other same rt value was seen already (like in ion mobility mass
      // spectrometry, for example). Only increment the y value.

      res.first->second += sumY;
    }
    */
}


Trace
MsRunReaderTicChromatogram::getTicChromatogram() const
{
  // return m_ticChromMapTrace.toTrace();
  return m_ticChromTrace;
}

MsRunQualifiedSpectrumLoader::MsRunQualifiedSpectrumLoader()
{
}


MsRunQualifiedSpectrumLoader::~MsRunQualifiedSpectrumLoader()
{
}


bool
MsRunQualifiedSpectrumLoader::needPeakList() const
{
  return true;
}

void
MsRunQualifiedSpectrumLoader::spectrumListHasSize(std::size_t size [[maybe_unused]])
{
  m_qualifiedSpectrumList.clear();
}

void
MsRunQualifiedSpectrumLoader::setQualifiedMassSpectrum(
  const QualifiedMassSpectrum &qualified_mass_spectrum)
{
  qDebug() << qualified_mass_spectrum.getMassSpectrumId().getNativeId();
  m_qualifiedSpectrumList.push_back(qualified_mass_spectrum);
}

const std::vector<QualifiedMassSpectrum> &
MsRunQualifiedSpectrumLoader::getQualifiedMassSpectrumList() const
{
  return m_qualifiedSpectrumList;
}

void
MsRunQualifiedSpectrumLoader::clear()
{
  m_qualifiedSpectrumList.clear();
}
} // namespace pappso
