/**
 * \file pappsomspp/processing/project/projectparameters.h
 * \date 16/03/2024
 * \author Olivier Langella
 * \brief simple structure to store project parameters (identification,
 * filtering, quantification)
 */

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

#include <QString>
#include <QVariant>
#include <odsstream/calcwriterinterface.h>
#include <QCborStreamWriter>
#include <QJsonObject>
#include "pappsomspp/export-import-config.h"


namespace pappso
{
/** \def ProjectParamCategory parameter category
 */
enum class ProjectParamCategory : std::int8_t
{
  undefined      = 0, ///< undefined
  general        = 1, ///< concerning the whole process
  identification = 2, ///< concerning identification
  filter         = 3, ///< concerning filters (psm, peptide, protein validation)
  quantification = 4, ///< quantification
  instrument     = 5, ///< information about instrument
};

struct PMSPP_LIB_DECL ProjectParam
{
  QJsonObject toJsonObject() const;

  ProjectParamCategory category;
  QString name;
  QVariant value;
};

/**
 * @todo write docs
 */
class PMSPP_LIB_DECL ProjectParameters
{
  public:
  /**
   * Default constructor
   */
  ProjectParameters();

  ProjectParameters(const QJsonObject &json_parameters);

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

  /**
   * Destructor
   */
  ~ProjectParameters();

  ProjectParameters &operator=(const ProjectParameters &other);

  void writeParameters(CalcWriterInterface &writer) const;

  void writeParameters(QXmlStreamWriter &xml_writer) const;

  void writeParameters(QCborStreamWriter &cbor_writer) const;


  const QVariant getValue(ProjectParamCategory category, const QString &name) const;
  void setProjectParam(const ProjectParam &param);
  void merge(const ProjectParameters &parameters);

  std::size_t size() const;


  std::vector<ProjectParam> getProjectParamListByCategory(ProjectParamCategory category) const;

  QJsonObject toJsonObject() const;

  private:
  void writeCellVariant(CalcWriterInterface &writer, const QVariant &var) const;

  void writeXmlParameter(QXmlStreamWriter &writer, const ProjectParam &param) const;
  void writeXmlVariant(QXmlStreamWriter &writer, const QVariant &var) const;


  private:
  std::map<QString, ProjectParam> m_mapGeneralParameters;
  std::map<QString, ProjectParam> m_mapIdentificationParameters;
  std::map<QString, ProjectParam> m_mapFilterParameters;
  std::map<QString, ProjectParam> m_mapQuantificationParameters;
  std::map<QString, ProjectParam> m_mapInstrumentParameters;
};

} // namespace pappso
