/**
 * \file pappsomspp/processing/cbor/psm/psmproteinmap.h
 * \date 05/07/2025
 * \author Olivier Langella
 * \brief PAPPSO CBOR protein map
 */

/*******************************************************************************
 * 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/>.
 *
 ******************************************************************************/
#pragma once

#include "pappsomspp/export-import-config.h"
#include <map>
#include <QString>
#include "pappsomspp/core/protein/protein.h"
#include "pappsomspp/core/processing/cbor/cborstreamwriter.h"
#include "pappsomspp/core/processing/cbor/cborstreamreader.h"


namespace pappso
{
namespace cbor
{
namespace psm
{


struct PsmProtein
{
  std::shared_ptr<Protein> protein_sp = nullptr;
  bool isTarget                       = true;
  bool isContaminant                  = false;
  QCborMap cborEval;
};
/** @brief store PsmProtein in a map with accession as key
 *
 */
class PMSPP_LIB_DECL PsmProteinMap
{
  public:
  /**
   * Default constructor
   */
  PsmProteinMap();

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


  /** @brief standard map insert of a PsmProtein (accession is the key)
   *
   * @return standard C++ insert iterator on a map
   */
  std::pair<std::map<QString, PsmProtein>::iterator, bool> insert(const PsmProtein &psm_protein);

  /** @brief writes the protein map in a cbor output stream
   * this output a CborMap structure directly in the output stream
   *
   * @param writer the cbor output stream
   */
  void writeMap(CborStreamWriter &writer) const;


  /** @brief reads the protein map from a cbor input stream
   *
   * @param reader the cbor intput stream
   */
  void readMap(CborStreamReader &reader);

  /** @brief get protein map size
   */
  std::size_t size() const;


  /** @brief retrieve a PsmProtein with its accession
   * @return PsmProtein const reference
   */
  const pappso::cbor::psm::PsmProtein &getByAccession(const QString &accession) const;


  /** @brief merge with other protein map
   */
  void merge(const PsmProteinMap &other_protein_map);

  /** @brief reduce to protein accessions listed in input
   */
  void reduce(const QStringList &accession_list);

  std::map<QString, PsmProtein> &getProteinMap();

  private:
  std::map<QString, PsmProtein> m_proteinMap;
};
} // namespace psm
} // namespace cbor
} // namespace pappso
