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

#include <exception>
#include <iostream>
#include <ls-std/core/exception/FileOperationException.hpp>
#include <ls-std/io/FileOutputStream.hpp>
#include <ls-std/io/evaluator/FileExistenceEvaluator.hpp>

using ls::standard::core::Class;
using ls::standard::core::FileOperationException;
using ls::standard::core::type::byte_field;
using ls::standard::io::File;
using ls::standard::io::FileExistenceEvaluator;
using ls::standard::io::FileOutputStream;
using std::cout;
using std::endl;
using std::exception;
using std::ios;

FileOutputStream::FileOutputStream(const File &_file) : Class("FileOutputStream"), file(_file)
{
  this->_init();
}

FileOutputStream::FileOutputStream(const File &_file, const bool _append) : Class("FileOutputStream"), append(_append), file(_file)
{
  this->_init();
}

FileOutputStream::~FileOutputStream() noexcept
{
  try
  {
    this->_close();
  }
  catch (const exception &_exception)
  {
    cout << "could not close file output stream: " << _exception.what() << endl;
  }
}

void FileOutputStream::close()
{
  this->_close();
}

bool FileOutputStream::write(const byte_field &_data)
{
  bool succeeded{};

  if (this->outputStream.is_open())
  {
    if (this->outputStream << _data)
    {
      succeeded = true;
    }
  }
  else
  {
    throw FileOperationException{"operation: write"};
  }

  return succeeded;
}

void FileOutputStream::_close()
{
  if (this->outputStream.is_open())
  {
    this->outputStream.close();
  }
}

void FileOutputStream::_init()
{
  FileExistenceEvaluator{this->file.getAbsoluteFilePath()}.evaluate();

  if (this->append)
  {
    this->outputStream.open(this->file.getAbsoluteFilePath(), ios::out | ios::app);
  }
  else
  {
    this->outputStream.open(this->file.getAbsoluteFilePath());
  }
}
