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

#include <fstream>
#include <limits>
#include <ls-std/core/exception/FileOperationException.hpp>
#include <ls-std/io/FileReader.hpp>
#include <ls-std/io/evaluator/FileExistenceEvaluator.hpp>
#include <stdexcept>

using ls::standard::core::Class;
using ls::standard::core::FileOperationException;
using ls::standard::core::type::byte_field;
using ls::standard::core::type::byte_type;
using ls::standard::io::File;
using ls::standard::io::FileExistenceEvaluator;
using ls::standard::io::FileReader;
using std::ifstream;
using std::numeric_limits;
using std::overflow_error;
using std::streamsize;
using std::string;

FileReader::FileReader(const File &_file) : Class("FileReader"), file(_file)
{
  FileExistenceEvaluator{_file.getAbsoluteFilePath()}.evaluate();
}

FileReader::~FileReader() noexcept = default;

byte_field FileReader::read()
{
  ifstream inputStream{this->file.getAbsoluteFilePath(), ifstream::binary};
  const auto length = this->file.getSize();
  auto data = string(length, 'x');

  if (length > static_cast<size_t>(numeric_limits<streamsize>::max()))
  {
    throw overflow_error("file size too large to read");
  }

  inputStream.read(data.data(), static_cast<streamsize>(length));

  if (inputStream.fail())
  {
    throw FileOperationException{"operation: read"};
  }

  inputStream.close();
  return data;
}

void FileReader::reset(const File &_file)
{
  FileExistenceEvaluator{_file.getAbsoluteFilePath()}.evaluate();
  this->file = _file;
}
