/**
 * \file protein/proteinintegercode.h
 * \date 22/05/2023
 * \author Olivier Langella
 * \brief transform protein amino acid sequence into vectors of amino acid codes
 */


/*******************************************************************************
 * Copyright (c) 2023 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.fr>.
 *
 * This file is part of PAPPSOms++.
 *
 *     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/>.
 *
 ******************************************************************************/

#pragma once

#include "../exportinmportconfig.h"
#include "../amino_acid/aastringcodec.h"
#include "protein.h"
#include <vector>

namespace pappso
{

/**
 * @brief
 */
class PMSPP_LIB_DECL ProteinIntegerCode
{
  public:
  /**
   * Default constructor
   */
  ProteinIntegerCode(ProteinSp protein,
                     const AaStringCodec &codec,
                     std::size_t aa_str_max_size = 5);

  /**
   * Copy constructor
   *
   * @param other TODO
   */
  ProteinIntegerCode(const ProteinIntegerCode &other);

  /**
   * Destructor
   */
  virtual ~ProteinIntegerCode();

  const std::vector<std::uint8_t> &getSeqAaCode() const;

  const std::vector<std::uint32_t> &
  getPeptideCodedFragment(std::size_t size) const;


  /** @brief list of positions and matched codes along protein sequence
   */
  std::vector<std::pair<std::size_t, std::uint32_t>>
  match(const std::vector<uint32_t> &code_list) const;


  /** @brief process convolution of spectrum code list along protein sequence
   *
   * @param code_list_from_spectrum unique sorted sequence codes given by the
   * spectrum decoder
   */
  std::vector<double>
  convolution(const std::vector<uint32_t> &code_list_from_spectrum) const;

  pappso::ProteinSp getProteinSp() const;

  private:
  std::vector<std::uint32_t>
  computePeptideCodeFragments(const AaStringCodec &codec,
                              std::size_t fragment_size) const;

  double
  convolutionKernel(const std::vector<uint32_t> &spectrum_code_list,
                    std::vector<std::uint8_t>::const_iterator it_aa,
                    std::vector<std::uint32_t>::const_iterator it_couple,
                    std::vector<std::uint32_t>::const_iterator it_trio,
                    std::vector<std::uint32_t>::const_iterator it_quatro,
                    std::vector<std::uint32_t>::const_iterator it_cinqo) const;

  private:
  ProteinSp msp_protein;

  std::vector<std::uint8_t> m_seqAaCode;
  std::vector<std::vector<std::uint32_t>> m_peptideCodedFragments;
};

} // namespace pappso
