/**
 * \file pappsomspp/processing/cbor/cborstreamwriter.h
 * \date 08/07/2025
 * \author Olivier Langella
 * \brief PAPPSO CBOR stream reader
 *
 * QCborStreamReader overloaded with convenient functions
 */

/*******************************************************************************
 * 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/>.
 *
 ******************************************************************************/

#include "cborstreamreader.h"

namespace pappso
{
namespace cbor
{
CborStreamReader::CborStreamReader() : QCborStreamReader()
{
}

CborStreamReader::CborStreamReader(QIODevice *device) : QCborStreamReader(device)
{
}
CborStreamReader::~CborStreamReader()
{
}

bool
CborStreamReader::decodeString(QString &the_str)
{
  the_str.clear();
  auto r = readString();
  while(r.status == QCborStreamReader::Ok)
    {
      the_str += r.data;
      r = readString();
    }

  if(r.status == QCborStreamReader::Error)
    {
      // handle error condition
      the_str.clear();
      return false;
    }
  return true;
}


bool
CborStreamReader::readArray(std::vector<double> &double_list)
{
  enterContainer();
  while(!lastError() && hasNext())
    {
      if(isDouble())
        {
          double_list.push_back(toDouble());
        }
      else
        {
          return false;
        }
      next();
      //}
    }
  leaveContainer();
  return true;
}

bool
CborStreamReader::readArray(std::vector<std::uint8_t> &small_int_list)
{

  enterContainer();
  while(!lastError() && hasNext())
    {
      if(isInteger())
        {
          small_int_list.push_back(toInteger());
        }
      else
        {
          return false;
        }
      next();
      //}
    }
  leaveContainer();
  return true;
}

bool
CborStreamReader::readArray(std::vector<int> &positions)
{
  enterContainer();
  while(!lastError() && hasNext())
    {
      if(isInteger())
        {
          positions.push_back(toInteger());
        }
      else
        {
          return false;
        }
      next();
      //}
    }
  leaveContainer();
  return true;
}

bool
CborStreamReader::readArray(std::vector<std::size_t> &int_list)
{
  enterContainer();
  while(!lastError() && hasNext())
    {
      if(isUnsignedInteger())
        {
          int_list.push_back(toUnsignedInteger());
        }
      else
        {
          return false;
        }
      next();
      //}
    }
  leaveContainer();
  return true;
}

bool
CborStreamReader::readArray(std::vector<qint64> &int_list)
{
  enterContainer();
  while(!lastError() && hasNext())
    {
      if(isUnsignedInteger())
        {
          int_list.push_back(toUnsignedInteger());
        }
      else
        {
          return false;
        }
      next();
      //}
    }
  leaveContainer();
  return true;
}


bool
CborStreamReader::readArray(QStringList &str_list)
{
  enterContainer();
  QString the_str;
  while(!lastError() && hasNext())
    {
      if(decodeString(the_str))
        {
          str_list << the_str;
        }
      else
        {
          return false;
        }
    }
  leaveContainer();
  return true;
}
bool
CborStreamReader::readArray(std::vector<QString> &str_list)
{
  str_list.clear();
  str_list.reserve(length());
  enterContainer();
  QString the_str;
  while(!lastError() && hasNext())
    {
      if(decodeString(the_str))
        {
          str_list.push_back(the_str);
        }
      else
        {
          return false;
        }
    }
  leaveContainer();
  return true;
}

bool
CborStreamReader::readCborMap(QCborMap &cbor_map)
{
  cbor_map = QCborValue::fromCbor(*this).toMap();
  if(!lastError())
    {
      return true;
    }
  else
    {
      qDebug() << lastError().toString();
    }

  return false;
}

bool
CborStreamReader::readCborArray(QCborArray &cbor_array)
{
  cbor_array = QCborValue::fromCbor(*this).toArray();
  if(!lastError())
    {
      return true;
    }
  else
    {
      qDebug() << lastError().toString();
    }

  return false;
}

} // namespace cbor
} // namespace pappso
