#ifndef FILESERVER_SERVER_INTERNAL_HXX
#define FILESERVER_SERVER_INTERNAL_HXX

#include <botan_all.h>
#include "server.hxx"

// TODO log user action with __FUNC__
#define check_user() auto user = is_token_valid(token); if (!user || !user->enabled)
#define check_user_response() check_user() return { .e = "Unauthorized" }
#define check_user_optional() check_user() return "Unauthorized"

#if defined(BOTAN_HAS_SYSTEM_RNG)
    static std::unique_ptr<Botan::RNG> auth_rng = std::make_unique<Botan::System_RNG>();
#else
    static std::unique_ptr<Botan::RNG> auth_rng = std::make_unique<Botan::AutoSeeded_RNG>();
#endif

// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types#common_image_file_types
static const std::unordered_map<std::string, std::string> mime_type_map = {
        {".apng" , "image/apng"},
        {".avif" , "image/avif"},
        {".bmp"  , "image/bmp"},
        {".gif"  , "image/gif"},
        {".jpg"  , "image/jpeg"},
        {".jpeg" , "image/jpeg"},
        {".jfif" , "image/jpeg"},
        {".pjpeg", "image/jpeg"},
        {".pjp"  , "image/jpeg"},
        {".png"  , "image/png"},
        {".svg"  , "image/svg"},
        {".webp" , "image/webp"},

        {".aac"  , "audio/aac"},
        {".flac" , "audio/flac"},
        {".mp3"  , "audio/mp3"},
        {".m4a"  , "audio/mp4"},
        {".oga"  , "audio/ogg"},
        {".ogg"  , "audio/ogg"},
        {".wav"  , "audio/wav"},

        {".3gp"  , "video/3gpp"},
        {".mpg"  , "video/mpeg"},
        {".mpeg" , "video/mpeg"},
        {".mp4"  , "video/mp4"},
        {".m4v"  , "video/mp4"},
        {".m4p"  , "video/mp4"},
        {".ogv"  , "video/ogg"},
        {".mov"  , "video/quicktime"},
        {".webm" , "video/webm"},
        {".mkv"  , "video/x-matroska"},
        {".mk3d" , "video/x-matroska"},
        {".mks"  , "video/x-matroska"},

        {".pdf"  , "application/pdf"}
};


static const std::string& get_mime_type(const std::filesystem::path &filename) {
    static const std::string octet = "application/octet-stream";

    const auto &entry = mime_type_map.find(filename.extension());
    if (entry != mime_type_map.end())
        return entry->second;
    else
        return octet;
}

std::shared_ptr<Node> get_node(const std::shared_ptr<User>& user, std::uint64_t id);

#endif //FILESERVER_SERVER_INTERNAL_HXX
