
/*******************************************************************************
 * Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.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/>.
 *
 * Contributors:
 *     Olivier Langella <olivier.langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "fastafile.h"
#include <pappsomspp/core/fasta/fastareader.h>
#include <QStringList>
#include <QDebug>
#include <pappsomspp/core/exception/exceptionnotfound.h>

class AccessionContaminantReader : public pappso::FastaHandlerInterface
{
  public:
  AccessionContaminantReader(ProteinStore &protein_store)
    : _protein_store(protein_store){};

  void
  setSequence(const QString &description,
              const QString &sequence [[maybe_unused]]) override
  {
    // qDebug() << "PeptideReader::setSequence " << description << " "
    // <<sequence;
    QStringList descr_split = description.simplified().split(" ");
    QString accession       = descr_split.at(0);
    // qDebug() << "PeptideReader::setSequence " << accession << " "
    // <<accession;
    _protein_store.setContaminantAccession(accession);
  };

  private:
  ProteinStore &_protein_store;
};


class AccessionDecoyReader : public pappso::FastaHandlerInterface
{
  public:
  AccessionDecoyReader(ProteinStore &protein_store)
    : _protein_store(protein_store){};

  void
  setSequence(const QString &description,
              const QString &sequence [[maybe_unused]]) override
  {
    // qDebug() << "PeptideReader::setSequence " << description << " "
    // <<sequence;
    QStringList descr_split = description.simplified().split(" ");
    QString accession       = descr_split.at(0);
    _protein_store.setDecoyAccession(accession);
  };

  private:
  ProteinStore &_protein_store;
};


FastaFile::FastaFile(const QString &fasta_source) : m_fastaSource(fasta_source)
{
  qDebug() << "FastaFile::FastaFile " << fasta_source;
}
FastaFile::FastaFile(const QFileInfo &fasta_source)
  : m_fastaSource(fasta_source)
{
}
FastaFile::FastaFile(const FastaFile &other)
  : m_fastaSource(other.m_fastaSource)
{
}
FastaFile::~FastaFile()
{
}

void
FastaFile::setXmlId(const QString xmlid)
{
  m_xmlId = xmlid;
}
const QString &
FastaFile::getXmlId() const
{
  return m_xmlId;
}
const QString
FastaFile::getFilename() const
{
  return m_fastaSource.fileName();
}

const QString
FastaFile::getAbsoluteFilePath() const
{
  return m_fastaSource.absoluteFilePath();
}
void
FastaFile::setContaminants(ProteinStore &protein_store) const
{
  protein_store.addContaminantFastaFile(this);
  if(m_fastaSource.exists())
    {
      AccessionContaminantReader accession_reader(protein_store);
      pappso::FastaReader reader(accession_reader);
      QFile fasta_file(m_fastaSource.absoluteFilePath());
      if(fasta_file.open(QIODevice::ReadOnly))
        {
          reader.parse(&fasta_file);
          fasta_file.close();
        }
      else
        {
          qDebug() << "FastaFile::setContaminants "
                   << m_fastaSource.absoluteFilePath() << " not open";
          throw pappso::ExceptionNotFound(
            QObject::tr("unable to open contaminant fasta file \"%1\"")
              .arg(m_fastaSource.absoluteFilePath()));
        }
    }
  else
    {
      qDebug() << "FastaFile::setContaminants "
               << m_fastaSource.absoluteFilePath() << " does not exists";
      throw pappso::ExceptionNotFound(
        QObject::tr("contaminant fasta file \"%1\" not found")
          .arg(m_fastaSource.absoluteFilePath()));
    }
}

void
FastaFile::setDecoys(ProteinStore &protein_store) const
{
  protein_store.addDecoyFastaFile(this);
  if(m_fastaSource.exists())
    {
      AccessionDecoyReader accession_reader(protein_store);
      pappso::FastaReader reader(accession_reader);
      QFile fasta_file(m_fastaSource.absoluteFilePath());
      if(fasta_file.open(QIODevice::ReadOnly))
        {
          reader.parse(&fasta_file);
          fasta_file.close();
        }
      else
        {
          qDebug() << "FastaFile::setDecoys "
                   << m_fastaSource.absoluteFilePath() << " not open";
          throw pappso::ExceptionNotFound(
            QObject::tr("unable to open decoy fasta file \"%1\"")
              .arg(m_fastaSource.absoluteFilePath()));
        }
    }
  else
    {
      qDebug() << "FastaFile::setDecoys " << m_fastaSource.absoluteFilePath()
               << " does not exists";
      throw pappso::ExceptionNotFound(
        QObject::tr("decoy fasta file \"%1\" not found")
          .arg(m_fastaSource.absoluteFilePath()));
    }
}


void
FastaFile::setFastaSource(const QString &fasta_file_location)
{
  qDebug() << fasta_file_location;
  m_fastaSource = QFileInfo(fasta_file_location);
}

const QFileInfo &
FastaFile::getQFileInfo() const
{
  return m_fastaSource;
}
