/**
 * \file pappsomspp/processing/specpeptidoms/correctiontree.cpp
 * \date 24/03/2025
 * \author Aurélien Berthier
 * \brief save corrections to apply
 *
 * C++ implementation of the SpecPeptidOMS algorithm described in :
 * (1) Benoist, É.; Jean, G.; Rogniaux, H.; Fertin, G.; Tessier, D. SpecPeptidOMS Directly and
 * Rapidly Aligns Mass Spectra on Whole Proteomes and Identifies Peptides That Are Not Necessarily
 * Tryptic: Implications for Peptidomics. J. Proteome Res. 2025.
 * https://doi.org/10.1021/acs.jproteome.4c00870.
 */

/*
 * Copyright (c) 2025 Aurélien Berthier
 * <aurelien.berthier@ls2n.fr>
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "correctiontree.h"

#include <QDebug>

pappso::specpeptidoms::CorrectionTree::CorrectionTree() : peak(0)
{
}

pappso::specpeptidoms::CorrectionTree::CorrectionTree(std::size_t peak) : peak(peak)
{
}

pappso::specpeptidoms::CorrectionTree::~CorrectionTree()
{
}

void
pappso::specpeptidoms::CorrectionTree::addPeaks(std::size_t peak1, std::size_t peak2)
{
  if(msp_left != nullptr)
    {
      msp_left->addPeaks(peak1, peak2);
      msp_right->addPeaks(peak1, peak2);
    }
  else
    {
      msp_left  = std::make_shared<CorrectionTree>(CorrectionTree(peak1));
      msp_right = std::make_shared<CorrectionTree>(CorrectionTree(peak2));
    }
}

std::vector<std::vector<std::size_t>>
pappso::specpeptidoms::CorrectionTree::getPeaks() const
{
  std::vector<std::vector<std::size_t>> v_left, v_right;
  if(peak == 0 && msp_left != nullptr)
    {
      v_left  = msp_left->getPeaks();
      v_right = msp_right->getPeaks();
      v_left.insert(v_left.end(), v_right.begin(), v_right.end());
    }
  else if(peak > 0 && msp_left != nullptr)
    {
      v_left  = msp_left->getPeaks();
      v_right = msp_right->getPeaks();
      v_left.insert(v_left.end(), v_right.begin(), v_right.end());
      for(auto vec = v_left.begin(); vec != v_left.end(); vec++)
        {
          vec->push_back(peak);
        }
    }
  else if(peak > 0)
    {
      v_left.push_back({peak});
    }
  return v_left;
}
