/**
 * \file pappsomspp/core/processing/cbor/mzcbor/mzcborbuildindexreader.cpp
 * \date 24/11/2025
 * \author Olivier Langella
 * \brief read mzcbor to build an index
 */

/*******************************************************************************
 * Copyright (c) 2025 Olivier Langella <Olivier.Langella@universite-paris-saclay.fr>.
 *
 * This file is part of PAPPSOms-tools.
 *
 *     PAPPSOms-tools 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-tools 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-tools.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/


#include "mzcborbuildindexreader.h"
#include "pappsomspp/core/pappsoexception.h"


namespace pappso
{
namespace cbor
{
namespace mzcbor
{
MzcborBuildIndexReader::MzcborBuildIndexReader(const MsRunIdCstSPtr &msrun_id)
  : mcsp_msRunId(msrun_id)
{
  m_xmlMzMlRunId = msrun_id.get()->getRunId();
}

MzcborBuildIndexReader::~MzcborBuildIndexReader()
{
}


void
MzcborBuildIndexReader::readCbor(QFile *cborp, pappso::UiMonitorInterface &monitor)
{
  qDebug();
  initCborReader((QIODevice *)cborp);

  if(mpa_cborReader->device() == nullptr)
    {
      throw pappso::PappsoException(QObject::tr("device is null"));
    }

  qDebug();
  if(mpa_cborReader->isMap())
    {
      readRoot(monitor);
    }
  qDebug();
}

const std::vector<qint64> &
MzcborBuildIndexReader::getSpectrumIndexPositionInFile() const
{
  return m_spectrumIndexPositionInFile;
}

const std::map<QString, std::size_t> &
MzcborBuildIndexReader::getNativeId2SpectrumIndexMap() const
{
  return m_nativeId2SpectrumIndexMap;
}
void
MzcborBuildIndexReader::readMsrun()
{
  // qDebug();

  mpa_cborReader->enterContainer();
  bool ms_run_to_read = false;

  while(getExpectedString())
    {
      if(m_expectedString == "id")
        {
          getExpectedString();

          if((m_expectedString == m_xmlMzMlRunId) || (m_xmlMzMlRunId.isEmpty()))
            {
              ms_run_to_read = true;
            }
        }
      else if(m_expectedString == "spectrumList")
        {
          if(ms_run_to_read)
            {
              readSpectrumListAndLeave();
            }
          else
            {
              mpa_cborReader->next();
            }
        }
      else
        {
          mpa_cborReader->next();
        }
    }

  mpa_cborReader->leaveContainer();
}


void
MzcborBuildIndexReader::readSpectrumListAndLeave()
{

  mpa_cborReader->enterContainer();


  // qDebug();

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

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

  while(getExpectedString())
    {

      qDebug() << m_expectedString;
      if(m_expectedString == "count")
        {
          if(mpa_cborReader->isUnsignedInteger())
            {
              spectrum_list_size = mpa_cborReader->toUnsignedInteger();
              mpa_cborReader->next();
              qDebug() << "spectrum count=" << spectrum_list_size;
            }
        }
      else if(m_expectedString == "spectrum")
        {

          mpa_cborReader->enterContainer(); // start array
          qint64 pos = mpa_cborReader->currentOffset();

          std::size_t index_count = 0;
          while(mpa_cborReader->hasNext())
            {
              qDebug();
              qDebug();
              readSpectrum(pos, index_count);
              index_count++;
              pos = mpa_cborReader->currentOffset();
            }

          mpa_cborReader->leaveContainer(); // stop array
        }
      else
        {
          mpa_cborReader->next();
        }
    }


  mpa_cborReader->leaveContainer();
  m_stopParsing = true;
}


void
MzcborBuildIndexReader::readSpectrum(qint64 position_of_spectrum_in_file, std::size_t index_count)
{
  qDebug();
  mpa_cborReader->enterContainer();
  //<spectrum id="controllerType=0 controllerNumber=1 scan=1" index="0" defaultArrayLength="1552">
  QString native_id;
  std::size_t given_index = 0;
  std::map<QString, CvParam> spectrum_parameters;
  std::map<QString, CvParam> scan_parameters;


  while(getExpectedString())
    {
      qDebug() << m_expectedString;
      if(m_expectedString == "id")
        {
          getExpectedString();
          native_id = m_expectedString;
          qDebug() << m_expectedString;
        }
      else if(m_expectedString == "index")
        {
          if(mpa_cborReader->isUnsignedInteger())
            {
              given_index = mpa_cborReader->toUnsignedInteger();
              mpa_cborReader->next();

              qDebug() << given_index;
              // qFatal();
            }
          else
            {
            }
        }
      else if(m_expectedString == "cvParam")
        {

          mpa_cborReader->next();
          // spectrum_parameters = getCvParamsMap();
        }
      else if(m_expectedString == "scanList")
        {
          mpa_cborReader->next();
        }
      else if(m_expectedString == "binaryDataArray")
        {
          mpa_cborReader->next();
        }
      else
        {
          mpa_cborReader->next();
        }
    }
  if((given_index != index_count) || (index_count != m_spectrumIndexPositionInFile.size()))
    {
      throw pappso::PappsoException(QObject::tr("index inconsistency %1 %2 %3")
                                      .arg(given_index)
                                      .arg(index_count)
                                      .arg(m_spectrumIndexPositionInFile.size()));
    }
  m_spectrumIndexPositionInFile.push_back(position_of_spectrum_in_file);

  m_nativeId2SpectrumIndexMap.insert({native_id, given_index});

  mpa_cborReader->leaveContainer();
}

} // namespace mzcbor
} // namespace cbor
} // namespace pappso
