#pragma once

#include "app.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "routing.hpp"
#include "webroutes.hpp"

#include <boost/container/flat_set.hpp>

#include <algorithm>
#include <array>
#include <filesystem>
#include <fstream>
#include <string>
#include <string_view>

namespace crow
{
namespace webassets
{

inline std::string getStaticEtag(const std::filesystem::path& webpath)
{
    // webpack outputs production chunks in the form:
    // <filename>.<hash>.<extension>
    // For example app.63e2c453.css
    // Try to detect this, so we can use the hash as the ETAG
    std::vector<std::string> split;
    bmcweb::split(split, webpath.filename().string(), '.');
    BMCWEB_LOG_DEBUG("Checking {} split.size() {}", webpath.filename().string(),
                     split.size());
    if (split.size() < 3)
    {
        return "";
    }

    // get the second to last element
    std::string hash = split.rbegin()[1];

    // Webpack hashes are 8 characters long
    if (hash.size() != 8)
    {
        return "";
    }
    // Webpack hashes only include hex printable characters
    if (hash.find_first_not_of("0123456789abcdefABCDEF") != std::string::npos)
    {
        return "";
    }
    return std::format("\"{}\"", hash);
}

static constexpr std::string_view rootpath("/usr/share/www/");

struct StaticFile
{
    std::filesystem::path absolutePath;
    std::string_view contentType;
    std::string_view contentEncoding;
    std::string etag;
    bool renamed = false;
};

inline void
    handleStaticAsset(const crow::Request& req,
                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const StaticFile& file)
{
    if (!file.contentType.empty())
    {
        asyncResp->res.addHeader(boost::beast::http::field::content_type,
                                 file.contentType);
    }

    if (!file.contentEncoding.empty())
    {
        asyncResp->res.addHeader(boost::beast::http::field::content_encoding,
                                 file.contentEncoding);
    }

    if (!file.etag.empty())
    {
        asyncResp->res.addHeader(boost::beast::http::field::etag, file.etag);
        // Don't cache paths that don't have the etag in them, like
        // index, which gets transformed to /
        if (!file.renamed)
        {
            // Anything with a hash can be cached forever and is
            // immutable
            asyncResp->res.addHeader(boost::beast::http::field::cache_control,
                                     "max-age=31556926, immutable");
        }

        std::string_view cachedEtag =
            req.getHeaderValue(boost::beast::http::field::if_none_match);
        if (cachedEtag == file.etag)
        {
            asyncResp->res.result(boost::beast::http::status::not_modified);
            return;
        }
    }

    if (!asyncResp->res.openFile(file.absolutePath))
    {
        BMCWEB_LOG_DEBUG("failed to read file");
        asyncResp->res.result(
            boost::beast::http::status::internal_server_error);
        return;
    }
}

inline std::string_view getFiletypeForExtension(std::string_view extension)
{
    constexpr static std::array<std::pair<std::string_view, std::string_view>,
                                17>
        contentTypes{
            {{".css", "text/css;charset=UTF-8"},
             {".eot", "application/vnd.ms-fontobject"},
             {".gif", "image/gif"},
             {".html", "text/html;charset=UTF-8"},
             {".ico", "image/x-icon"},
             {".jpeg", "image/jpeg"},
             {".jpg", "image/jpeg"},
             {".js", "application/javascript;charset=UTF-8"},
             {".json", "application/json"},
             // dev tools don't care about map type, setting to json causes
             // browser to show as text
             // https://stackoverflow.com/questions/19911929/what-mime-type-should-i-use-for-javascript-source-map-files
             {".map", "application/json"},
             {".png", "image/png;charset=UTF-8"},
             {".svg", "image/svg+xml"},
             {".ttf", "application/x-font-ttf"},
             {".woff", "application/x-font-woff"},
             {".woff2", "application/x-font-woff2"},
             {".xml", "application/xml"}}};

    const auto* contentType = std::ranges::find_if(
        contentTypes,
        [&extension](const auto& val) { return val.first == extension; });

    if (contentType == contentTypes.end())
    {
        BMCWEB_LOG_ERROR(
            "Cannot determine content-type for file with extension {}",
            extension);
        return "";
    }
    return contentType->second;
}

inline void addFile(App& app, const std::filesystem::directory_entry& dir)
{
    StaticFile file;
    file.absolutePath = dir.path();
    std::filesystem::path relativePath(
        file.absolutePath.string().substr(rootpath.size() - 1));

    std::string extension = relativePath.extension();
    std::filesystem::path webpath = relativePath;

    if (extension == ".gz")
    {
        webpath = webpath.replace_extension("");
        // Use the non-gzip version for determining content type
        extension = webpath.extension().string();
        file.contentEncoding = "gzip";
    }

    file.etag = getStaticEtag(webpath);

    if (webpath.filename().string().starts_with("index."))
    {
        webpath = webpath.parent_path();
        if (webpath.string().empty() || webpath.string().back() != '/')
        {
            // insert the non-directory version of this path
            webroutes::routes.insert(webpath);
            webpath += "/";
            file.renamed = true;
        }
    }

    std::pair<boost::container::flat_set<std::string>::iterator, bool>
        inserted = webroutes::routes.insert(webpath);

    if (!inserted.second)
    {
        // Got a duplicated path.  This is expected in certain
        // situations
        BMCWEB_LOG_DEBUG("Got duplicated path {}", webpath.string());
        return;
    }
    file.contentType = getFiletypeForExtension(extension);

    if (webpath == "/")
    {
        forward_unauthorized::hasWebuiRoute = true;
    }

    app.routeDynamic(webpath)(
        [file = std::move(file)](
            const crow::Request& req,
            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        handleStaticAsset(req, asyncResp, file);
    });
}

inline void requestRoutes(App& app)
{
    std::error_code ec;
    std::filesystem::recursive_directory_iterator dirIter({rootpath}, ec);
    if (ec)
    {
        BMCWEB_LOG_ERROR(
            "Unable to find or open {} static file hosting disabled", rootpath);
        return;
    }

    // In certain cases, we might have both a gzipped version of the file AND a
    // non-gzipped version.  To avoid duplicated routes, we need to make sure we
    // get the gzipped version first.  Because the gzipped path should be longer
    // than the non gzipped path, if we sort in descending order, we should be
    // guaranteed to get the gzip version first.
    std::vector<std::filesystem::directory_entry> paths(
        std::filesystem::begin(dirIter), std::filesystem::end(dirIter));
    std::sort(paths.rbegin(), paths.rend());

    for (const std::filesystem::directory_entry& dir : paths)
    {
        if (std::filesystem::is_directory(dir))
        {
            // don't recurse into hidden directories or symlinks
            if (dir.path().filename().string().starts_with(".") ||
                std::filesystem::is_symlink(dir))
            {
                dirIter.disable_recursion_pending();
            }
        }
        else if (std::filesystem::is_regular_file(dir))
        {
            addFile(app, dir);
        }
    }
}
} // namespace webassets
} // namespace crow
