#include "util/file_util.hpp"

#include <fstream>
#include <sstream>

namespace fs = std::filesystem;

namespace lm {

std::string FileUtil::readBinary(const fs::path& path)
{
  std::ifstream in(path, std::ios::binary);
  if (!in)
    return {};
  std::ostringstream ss;
  ss << in.rdbuf();
  return ss.str();
}

bool FileUtil::writeBinaryAtomic(const fs::path& path, const std::string& contents)
{
  fs::create_directories(path.parent_path());
  auto tmp = path;
  tmp += ".tmp";

  {
    std::ofstream out(tmp, std::ios::binary | std::ios::trunc);
    if (!out)
      return false;
    out.write(contents.data(), static_cast<std::streamsize>(contents.size()));
    out.flush();
    if (!out)
      return false;
  }

  std::error_code ec;
  fs::rename(tmp, path, ec);
  if (!ec)
    return true;

  fs::remove(path, ec);
  ec.clear();
  fs::rename(tmp, path, ec);
  return !ec;
}

}  // namespace lm
