#include "file_test_utilities.hpp"
#include "http/http_body.hpp"
#include "http/http_response.hpp"
#include "utility.hpp"

#include <boost/beast/core/buffers_to_string.hpp>
#include <boost/beast/core/file_base.hpp>
#include <boost/beast/core/file_posix.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/beast/http/serializer.hpp>
#include <boost/beast/http/status.hpp>

#include <cstdio>
#include <filesystem>
#include <string>

#include "gtest/gtest.h"
namespace
{
void addHeaders(crow::Response& res)
{
    res.addHeader("myheader", "myvalue");
    res.keepAlive(true);
    res.result(boost::beast::http::status::ok);
}
void verifyHeaders(crow::Response& res)
{
    EXPECT_EQ(res.getHeaderValue("myheader"), "myvalue");
    EXPECT_EQ(res.keepAlive(), true);
    EXPECT_EQ(res.result(), boost::beast::http::status::ok);
}

std::string getData(boost::beast::http::response<bmcweb::HttpBody>& m)
{
    std::string ret;

    boost::beast::http::response_serializer<bmcweb::HttpBody> sr{m};
    sr.split(true);
    // Reads buffers into ret
    auto reader = [&sr, &ret](const boost::system::error_code& ec2,
                              const auto& buffer) {
        EXPECT_FALSE(ec2);
        std::string ret2 = boost::beast::buffers_to_string(buffer);
        sr.consume(ret2.size());
        ret += ret2;
    };
    boost::system::error_code ec;

    // Read headers
    while (!sr.is_header_done())
    {
        sr.next(ec, reader);
        EXPECT_FALSE(ec);
    }
    ret.clear();

    // Read body
    while (!sr.is_done())
    {
        sr.next(ec, reader);
        EXPECT_FALSE(ec);
    }

    return ret;
}

TEST(HttpResponse, Headers)
{
    crow::Response res;
    addHeaders(res);
    verifyHeaders(res);
}
TEST(HttpResponse, StringBody)
{
    crow::Response res;
    addHeaders(res);
    std::string_view bodyValue = "this is my new body";
    res.write({bodyValue.data(), bodyValue.length()});
    EXPECT_EQ(*res.body(), bodyValue);
    verifyHeaders(res);
}
TEST(HttpResponse, HttpBody)
{
    crow::Response res;
    addHeaders(res);
    TemporaryFileHandle temporaryFile("sample text");
    res.openFile(temporaryFile.stringPath);

    verifyHeaders(res);
}
TEST(HttpResponse, HttpBodyWithFd)
{
    crow::Response res;
    addHeaders(res);
    TemporaryFileHandle temporaryFile("sample text");
    FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r+");
    res.openFd(fileno(fd));
    verifyHeaders(res);
    fclose(fd);
}

TEST(HttpResponse, Base64HttpBodyWithFd)
{
    crow::Response res;
    addHeaders(res);
    TemporaryFileHandle temporaryFile("sample text");
    FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r");
    ASSERT_NE(fd, nullptr);
    res.openFd(fileno(fd), bmcweb::EncodingType::Base64);
    verifyHeaders(res);
    fclose(fd);
}

TEST(HttpResponse, BodyTransitions)
{
    crow::Response res;
    addHeaders(res);
    TemporaryFileHandle temporaryFile("sample text");
    res.openFile(temporaryFile.stringPath);

    verifyHeaders(res);
    res.write("body text");

    verifyHeaders(res);
}

std::string generateBigdata()
{
    std::string result;
    while (result.size() < 10000)
    {
        result += "sample text";
    }
    return result;
}

TEST(HttpResponse, StringBodyWriterLarge)
{
    crow::Response res;
    std::string data = generateBigdata();
    res.write(std::string(data));
    EXPECT_EQ(getData(res.response), data);
}

TEST(HttpResponse, Base64HttpBodyWriter)
{
    crow::Response res;
    std::string data = "sample text";
    TemporaryFileHandle temporaryFile(data);
    FILE* f = fopen(temporaryFile.stringPath.c_str(), "r+");
    res.openFd(fileno(f), bmcweb::EncodingType::Base64);
    EXPECT_EQ(getData(res.response), "c2FtcGxlIHRleHQ=");
}

TEST(HttpResponse, Base64HttpBodyWriterLarge)
{
    crow::Response res;
    std::string data = generateBigdata();
    TemporaryFileHandle temporaryFile(data);

    boost::beast::file_posix file;
    boost::system::error_code ec;
    file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
              ec);
    EXPECT_EQ(ec.value(), 0);
    res.openFd(file.native_handle(), bmcweb::EncodingType::Base64);
    EXPECT_EQ(getData(res.response), crow::utility::base64encode(data));
}

TEST(HttpResponse, HttpBodyWriterLarge)
{
    crow::Response res;
    std::string data = generateBigdata();
    TemporaryFileHandle temporaryFile(data);

    boost::beast::file_posix file;
    boost::system::error_code ec;
    file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
              ec);
    EXPECT_EQ(ec.value(), 0);
    res.openFd(file.native_handle());
    EXPECT_EQ(getData(res.response), data);
}

} // namespace
