/////////////////////// StdLib includes
#include <iostream>
#include <iomanip>


/////////////////////// Qt includes
#include <QDebug>
#include <QFile>
#include <QFileInfo>


/////////////////////// libpwiz includes
#include <pwiz/data/msdata/DefaultReaderList.hpp>


/////////////////////// Local includes
#include "xymsfilereader.h"
#include "../exception/exceptionnotfound.h"
#include "../utils.h"
#include "../types.h"
#include "../msrun/msrunid.h"


namespace pappso
{


XyMsFileReader::XyMsFileReader(const QString &file_name)
  : MsFileReader{file_name}
{
}


XyMsFileReader::~XyMsFileReader()
{
}


bool
XyMsFileReader::initialize(std::size_t &line_count)
{
  // Here we just test all the lines of the file to check that they comply with
  // the xy format.

  line_count = 0;

  QFile file(m_fileName);

  if(!file.open(QFile::ReadOnly | QFile::Text))
    {
      qDebug() << "Failed to open file" << m_fileName;

      return 0;
    }

  QRegularExpressionMatch regExpMatch;

  QString line;
  bool file_reading_failed = false;

  while(!file.atEnd())
    {
      line = file.readLine();

      // We only read a given number of lines from the file, that would be
      // enough to check if that file has the right syntax or not.
      // if(linesRead >= 2000)
      // return true;

      if(line.startsWith('#') || line.isEmpty() ||
         Utils::endOfLineRegExp.match(line).hasMatch())
        continue;

      qDebug() << "Current xy format line:" << line;

      if(Utils::xyMassDataFormatRegExp.match(line).hasMatch())
        {
          ++line_count;
          continue;
        }
      else
        {
          // the first line of the text file may include column titles
          if(line_count > 0)
            {
              file_reading_failed = true;
              break;
            }
        }
    }

  if(!file_reading_failed && line_count >= 1)
    {
      m_fileFormat = MsDataFormat::xy;
      return true;
    }

  m_fileFormat = MsDataFormat::unknown;

  // qDebug() << "m_fileFormat: " << static_cast<int>(m_fileFormat);

  return false;
}


MsDataFormat
XyMsFileReader::getFileFormat()
{
  return m_fileFormat;
}


std::vector<MsRunIdCstSPtr>
XyMsFileReader::getMsRunIds(const QString &run_prefix)
{
  std::vector<MsRunIdCstSPtr> ms_run_ids;

  std::size_t line_count = 0;

  if(!initialize(line_count))
    return ms_run_ids;

  // Finally create the MsRunId with the file name.
  MsRunId ms_run_id(m_fileName);
  ms_run_id.setMsDataFormat(m_fileFormat);

  // We need to set the unambiguous xmlId string.
  ms_run_id.setXmlId(
    QString("%1%2").arg(run_prefix).arg(Utils::getLexicalOrderedString(0)));

  // Craft a meaningful sample name because otherwise all the files loaded from
  // text files will have the same sample name and it will be difficult to
  // differentiate them.
  // Orig version:
  // ms_run_id.setRunId("Single spectrum");
  // Now the sample name is nothing but the file name without the path.

  QFileInfo file_info(m_fileName);

  // qDebug() << "file name:" << m_fileName;

  QString sample_name = file_info.fileName();

  // qDebug() << "sample name:" << sample_name;

  ms_run_id.setRunId(sample_name);

  // Now set the sample name to the run id:

  ms_run_id.setSampleName(ms_run_id.getRunId());

  // Now set the sample name to the run id:

  ms_run_id.setSampleName(ms_run_id.getRunId());

  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
  //<< "Current ms_run_id:" << ms_run_id.toString();

  // Finally make a shared pointer out of it and append it to the vector.
  ms_run_ids.push_back(std::make_shared<MsRunId>(ms_run_id));

  return ms_run_ids;
}


} // namespace pappso
