#include "core/io.hpp"

#include "errors/exceptions.hpp"

extern "C"
{
#if defined(__linux__)
#include <pwd.h>
#include <unistd.h>
#endif
}

#include <cstddef>
#include <cstdio>
#include <format>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>

using namespace kuiper;

std::string io::read_text_file(const std::filesystem::path& path) noexcept {
    if (path.empty() || !std::filesystem::is_regular_file(path) || !std::filesystem::exists(path)) {
        return "";
    }

    auto input_file = std::ifstream(path, std::ios::ate);
    if (!input_file.is_open()) {
        return "";
    }

    const auto file_size = input_file.tellg();
    input_file.seekg(0);

    // Use std::stringstream here (?)
    std::string buf(static_cast<std::size_t>(file_size) + 1, '\0');
    input_file.read(&buf[0], file_size);
    input_file.close();

    return buf;
}

std::filesystem::path io::get_home_dir() noexcept {
#if defined(__linux__)
    const auto uid = getuid();
    const auto pw  = getpwuid(uid);
    return {pw->pw_dir};
#endif

    return {};
}
