#include "resource.h"
#include <boost/log/trivial.hpp>
#include <fstream>

static void loadFile(const std::string& path, std::vector<char>& content) {
    std::ifstream is(path, std::ios::in | std::ios::binary);
    if (!is) {
        throw std::runtime_error("File not found");
    }

    content.clear();
    for (;;) {
        char buf[512];
        auto len = is.read(buf, sizeof(buf)).gcount();
        if (len <= 0) {
            break;
        }
        content.insert(content.end(), buf, buf + len);
    }
}

http::resource::StaticFileResource::StaticFileResource(const std::string &path, const std::string &filePath, server::mime_types::Mime type): type(type) {
    this->path = path;
#ifdef USE_DEBUG
    BOOST_LOG_TRIVIAL(info) << "Skip loading file " << filePath << " (http path: " << path << ")";
    this->filePath = filePath;
#else
    BOOST_LOG_TRIVIAL(info) << "Load file " << filePath << " (http path: " << path << ")";
    loadFile(filePath, this->content);
#endif
}

void http::resource::StaticFileResource::handle(const server::Request &req, server::reply &rep) {
    if (req.method != "GET") {
        stockReply(server::bad_request, rep);
        return;
    }

    // TODO сделать поддержку range
#ifdef USE_DEBUG
    BOOST_LOG_TRIVIAL(debug) << "Reload file " << filePath << " (http path: " << path << ")";
    loadFile(this->filePath, rep.content);
#else
    rep.content.clear();
    rep.content.insert(rep.content.end(), this->content.begin(), this->content.end());
#endif
    rep.status = server::ok;
    rep.headers.clear();
    // TODO сделать cache control
    rep.headers.push_back({.name = "Content-Type", .value = toString(this->type)});
}

http::resource::StaticFileResource::~StaticFileResource() = default;

http::resource::GenericResource::GenericResource(const std::string &path, const respGenerator &generator): generator_(generator) {
    this->path = path;
}

void http::resource::GenericResource::handle(const server::Request &req, server::reply &rep) {
    this->generator_(req, rep);
}

http::resource::GenericResource::~GenericResource() = default;


