/**
 * \file utils/identificationdatasourcestore.cpp
 * \date 5/4/2017
 * \author Olivier Langella
 * \brief store unique version of identification data sources (output files from
 * identification engines)
 */


/*******************************************************************************
 * Copyright (c) 2017 Olivier Langella <Olivier.Langella@u-psud.fr>.
 *
 * This file is part of XTPcpp.
 *
 *     XTPcpp 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.
 *
 *     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "identificationdatasourcestore.h"
#include "../core/identification_sources/identificationxtandemfile.h"
#include "../core/identification_sources/identificationmascotdatfile.h"
#include "../core/identification_sources/identificationpwizfile.h"
#include "../core/identification_sources/identificationpepxmlfile.h"
#include <pappsomspp/pappsoexception.h>
#include <pappsomspp/utils.h>

IdentificationDataSourceStore::IdentificationDataSourceStore()
{
}

IdentificationDataSourceStore::~IdentificationDataSourceStore()
{
}

IdentificationDataSourceSp
IdentificationDataSourceStore::getInstance(const QString &location,
                                           IdentificationEngine engine)
{
  // TODO file format read needs a fix
  qDebug() << "IdentificationDataSourceStore::getInstance begin " << location;
  std::map<QString, IdentificationDataSourceSp>::iterator it =
    _map_identification_data_sources.find(location);
  if(it != _map_identification_data_sources.end())
    {
      qDebug() << "IdentificationDataSourceStore::getInstance found "
               << location;
      return it->second;
    }
  else
    {
      QFileInfo location_file(location);
      QString ext = location_file.suffix();
      qDebug() << "IdentificationDataSourceStore::getInstance coucou 1 ";
      // QString sample_name = location_file.baseName();
      IdentificationDataSourceSp p_identfile = nullptr;
      switch(engine)
        {
          case IdentificationEngine::mascot:
            p_identfile =
              std::make_shared<IdentificationMascotDatFile>(location_file);
            break;

          case IdentificationEngine::XTandem:
            p_identfile =
              std::make_shared<IdentificationXtandemFile>(location_file);
            break;

          case IdentificationEngine::Comet:
            p_identfile =
              std::make_shared<IdentificationPepXmlFile>(location_file);
            break;

          case IdentificationEngine::SEQUEST:
            p_identfile =
              std::make_shared<IdentificationPepXmlFile>(location_file);
            break;
          default:
            break;
        }
      if(p_identfile == nullptr)
        {
          throw pappso::PappsoException(
            QObject::tr(
              "Identification resource %1 not recognized (null pointer)")
              .arg(location));
        }
      qDebug() << "IdentificationDataSourceStore::getInstance coucou 2 ";
      p_identfile.get()->setXmlId(
        QString("ident%1").arg(pappso::Utils::getLexicalOrderedString(
          _map_identification_data_sources.size())));
      p_identfile.get()->setIdentificationEngine(engine);
      _map_identification_data_sources.insert(
        std::pair<QString, IdentificationDataSourceSp>(location, p_identfile));
      _map_identification_data_sources.insert(
        std::pair<QString, IdentificationDataSourceSp>(
          location_file.absoluteFilePath(), p_identfile));
      qDebug() << "IdentificationDataSourceStore::getInstance inserted "
               << location;
      return p_identfile;
    }
  throw pappso::PappsoException(
    QObject::tr("Identification resource %1 not recognized").arg(location));
}

IdentificationDataSourceSp
IdentificationDataSourceStore::getInstance(const QString &location)
{
  qDebug() << "IdentificationDataSourceStore::getInstance begin " << location;
  qDebug() << " " << _map_identification_data_sources.size();
  std::map<QString, IdentificationDataSourceSp>::iterator it =
    _map_identification_data_sources.find(location);
  if(it != _map_identification_data_sources.end())
    {
      return it->second;
    }
  else
    {
      QFileInfo location_file(location);
      QString ext = location_file.completeSuffix();
      // QString sample_name = location_file.baseName();
      IdentificationDataSourceSp p_identfile = nullptr;
      if((ext.toLower() == "xml") || (ext.toLower() == ".d.xml"))
        {
          // X!Tandem result file
          p_identfile =
            std::make_shared<IdentificationXtandemFile>(location_file);
        }
      else if(ext.toLower() == "pep")
        {
          // pep xml file
          p_identfile =
            std::make_shared<IdentificationPepXmlFile>(location_file);
        }
      else if(ext.toLower() == "pep.xml")
        {
          // pep xml file
          p_identfile =
            std::make_shared<IdentificationPepXmlFile>(location_file);
        }
      else if(ext.toLower() == "pepxml")
        {
          // pep xml file
          p_identfile =
            std::make_shared<IdentificationPepXmlFile>(location_file);
        }
      else if(ext.toLower() == "dat")
        {
          // MASCOT dat file
          p_identfile =
            std::make_shared<IdentificationMascotDatFile>(location_file);
        }
      else
        {
          // p_identfile =
          // std::make_shared<IdentificationPwizFile>(location_file);
        }
      if(p_identfile == nullptr)
        {
          throw pappso::PappsoException(
            QObject::tr(
              "Identification resource %1 not recognized (null pointer)")
              .arg(location));
        }
      p_identfile.get()->setXmlId(
        QString("ident%1").arg(pappso::Utils::getLexicalOrderedString(
          _map_identification_data_sources.size())));

      _map_identification_data_sources.insert(
        std::pair<QString, IdentificationDataSourceSp>(location, p_identfile));
      _map_identification_data_sources.insert(
        std::pair<QString, IdentificationDataSourceSp>(
          location_file.absoluteFilePath(), p_identfile));
      return p_identfile;
    }
  throw pappso::PappsoException(
    QObject::tr("Identification resource %1 not recognized").arg(location));
}


std::vector<IdentificationDataSourceSp>
IdentificationDataSourceStore::getIdentificationDataSourceList() const
{
  std::vector<IdentificationDataSourceSp> idsource_list;
  for(auto &msrun_pair : _map_identification_data_sources)
    {
      idsource_list.push_back(msrun_pair.second);
    }
  return idsource_list;
}
