#pragma once
#include "HttpUtils.h"
#include <drogon/HttpRequest.h>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <filesystem>
#include <string_view>
namespace drogon
{
class HttpFileImpl
{
  public:
    const std::string &getFileName() const noexcept
    {
        return fileName_;
    }
    void setFileName(const std::string &fileName) noexcept
    {
        fileName_ = fileName;
    }
    void setFileName(std::string &&fileName) noexcept
    {
        fileName_ = std::move(fileName);
    }
    std::string_view getFileExtension() const noexcept
    {
        return drogon::getFileExtension(fileName_);
    }
    void setFile(const char *data, size_t length) noexcept
    {
        fileContent_ = std::string_view{data, length};
    }
    int save() const noexcept;
    int save(const std::string &path) const noexcept;
    int saveAs(const std::string &fileName) const noexcept;
    size_t fileLength() const noexcept
    {
        return fileContent_.length();
    }
    const char *fileData() const noexcept
    {
        return fileContent_.data();
    }
    const std::string_view &fileContent() const noexcept
    {
        return fileContent_;
    }
    const std::string &getItemName() const noexcept
    {
        return itemName_;
    }
    void setItemName(const std::string &itemName) noexcept
    {
        itemName_ = itemName;
    }
    void setItemName(std::string &&itemName) noexcept
    {
        itemName_ = std::move(itemName);
    }
    FileType getFileType() const noexcept
    {
        auto ft = drogon::getFileType(contentType_);
        if ((ft != FT_UNKNOWN) && (ft != FT_CUSTOM))
            return ft;
        return parseFileType(getFileExtension());
    }
    std::string getMd5() const noexcept;
    std::string getSha256() const noexcept;
    std::string getSha3() const noexcept;
    int saveTo(const std::filesystem::path &pathAndFileName) const noexcept;
    void setRequest(const HttpRequestPtr &req) noexcept
    {
        requestPtr_ = req;
    }
    drogon::ContentType getContentType() const noexcept
    {
        return contentType_;
    }
    void setContentType(drogon::ContentType contentType) noexcept
    {
        contentType_ = contentType;
    }
    void setContentTransferEncoding(
        const std::string &contentTransferEncoding) noexcept
    {
        transferEncoding_ = contentTransferEncoding;
    }
    void setContentTransferEncoding(
        std::string &&contentTransferEncoding) noexcept
    {
        transferEncoding_ = std::move(contentTransferEncoding);
    }
    const std::string &getContentTransferEncoding() const noexcept
    {
        return transferEncoding_;
    }
  private:
    std::string fileName_;
    std::string itemName_;
    std::string transferEncoding_;
    std::string_view fileContent_;
    HttpRequestPtr requestPtr_;
    drogon::ContentType contentType_{drogon::CT_NONE};
};
}  