/*
* Author:          Patrick-Christopher Mattulat
* Co-Author:       Claude Sonnet 4.6 (LLM)
* Company:         Lynar Studios
* E-Mail:          webmaster@lynarstudios.com
* Created:         2023-02-11
* Changed:         2026-06-23
*
* */

#include <list>
#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
#include <ls-std/io/section-pair/SectionPairTypes.hpp>
#include <ls-std/io/section-pair/model/SectionPairRowListValue.hpp>
#include <ls-std/io/section-pair/serialization/SerializableSectionPairRowListValue.hpp>
#include <numeric>

using ls::standard::core::Class;
using ls::standard::core::EmptyStringArgumentEvaluator;
using ls::standard::core::NullPointerArgumentEvaluator;
using ls::standard::core::type::byte_field;
using ls::standard::io::SectionPairRowListValue;
using ls::standard::io::SerializableSectionPairParameter;
using ls::standard::io::SerializableSectionPairRowListValue;
using std::accumulate;
using std::dynamic_pointer_cast;
using std::list;
using std::move;
using std::shared_ptr;
using std::string;
using std::string_view;

SerializableSectionPairRowListValue::SerializableSectionPairRowListValue(const SerializableSectionPairParameter &_parameter) : Class("SerializableSectionPairRowListValue"), parameter(_parameter)
{
  const string message = this->getClassName() + ": model reference is null!";
  NullPointerArgumentEvaluator{_parameter.getValue(), message}.evaluate();
}

SerializableSectionPairRowListValue::~SerializableSectionPairRowListValue() noexcept = default;

shared_ptr<Class> SerializableSectionPairRowListValue::getValue() const
{
  return this->parameter.getValue();
}

byte_field SerializableSectionPairRowListValue::marshal()
{
  list<section_pair_row_value> listValue = dynamic_pointer_cast<SectionPairRowListValue>(this->getValue())->getList();
  return accumulate(listValue.begin(), listValue.end(), byte_field{}, [this](byte_field data, const byte_field &_value) { return ::move(data) + "  " + _value + this->parameter.getNewLine(); });
}

void SerializableSectionPairRowListValue::unmarshal(const byte_field &_data)
{
  EmptyStringArgumentEvaluator{_data}.evaluate();
  byte_field searchText = _data;
  const string newLine = this->parameter.getNewLine();

  while (!searchText.empty() && searchText != newLine)
  {
    const string::size_type positionOfNewLine = searchText.find(newLine);
    string line = _getLine(positionOfNewLine, searchText);
    line = line.substr(2);
    dynamic_pointer_cast<SectionPairRowListValue>(this->getValue())->add(line);
    this->_updateSearchText(positionOfNewLine, searchText);
  }
}

string SerializableSectionPairRowListValue::_getLine(const string::size_type _position, const string_view _searchText)
{
  string line{};

  if (_position != string::npos)
  {
    line = _searchText.substr(0, _position);
  }
  else
  {
    line = _searchText;
  }

  return line;
}

void SerializableSectionPairRowListValue::_updateSearchText(const string::size_type _position, byte_field &_searchText) const
{
  if (_position != string::npos)
  {
    _searchText = _searchText.substr(_position + this->parameter.getNewLine().size());
  }
  else
  {
    _searchText = "";
  }
}
