#include <cstdlib>
#include <stdplus/fd/fmt.hpp>
#include <stdplus/fd/ops.hpp>
#include <stdplus/util/cexec.hpp>
#include <sys/stat.h>

namespace stdplus
{
namespace fd
{

FormatBuffer::FormatBuffer(Fd& fd, size_t max) : fd(fd), max(max)
{
}

FormatBuffer::~FormatBuffer() noexcept(false)
{
    flush();
}

void FormatBuffer::flush()
{
    if (buf.size() > 0)
    {
        writeExact(fd, buf);
        buf.clear();
    }
}

void FormatBuffer::writeIfNeeded()
{
    if (buf.size() >= max)
    {
        flush();
    }
}

FormatToFile::FormatToFile(std::string_view tmpl) :
    tmpname(tmpl),
    fd(CHECK_ERRNO(mkstemp(tmpname.data()),
                   [&](int error) {
                       auto msg = fmt::format("mkstemp({})", tmpname);
                       tmpname.clear();
                       throw std::system_error(error, std::generic_category(),
                                               msg);
                   })),
    buf(fd)
{
}

FormatToFile::~FormatToFile()
{
    if (!tmpname.empty())
    {
        std::error_code ec;
        std::filesystem::remove(tmpname, ec);
    }
}

void FormatToFile::commit(const std::filesystem::path& out, int mode)
{
    {
        buf.flush();
        auto ifd = std::move(fd);
    }
    CHECK_ERRNO(chmod(tmpname.c_str(), mode), [&](int error) {
        throw std::system_error(error, std::generic_category(),
                                fmt::format("chmod({}, {})", tmpname, mode));
    });
    std::filesystem::rename(tmpname, out);
    tmpname.clear();
}

} // namespace fd
} // namespace stdplus
