BareGit
#pragma once

#include <filesystem>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

#include <httplib.h>
#include <mw/error.hpp>

/// Streamed fields and server-owned files from one card upload.
struct CardUpload
{
    /// Private directory containing the staged binary fields.
    std::filesystem::path staging_directory;

    /// Singleton text fields indexed by their form names.
    std::unordered_map<std::string, std::string> fields;

    /// Repeated series membership values in request order.
    std::vector<std::string> series_ids;

    /// Staged front artwork, when supplied.
    std::optional<std::filesystem::path> front;

    /// Staged foil-control image, when supplied.
    std::optional<std::filesystem::path> foil;

    /// Staged browser-rendered thumbnail, when supplied.
    std::optional<std::filesystem::path> thumbnail;
};

/// Stream a multipart card request into a private staging directory.
class MultipartReader
{
public:
    /// Construct a reader rooted below the private card storage directory.
    explicit MultipartReader(std::filesystem::path card_storage_root);

    /// Remove any staging directory which has not been published.
    ~MultipartReader();

    /// Prevent two readers from owning the same staging directory.
    MultipartReader(const MultipartReader&) = delete;

    /// Prevent reassignment of staging-directory cleanup ownership.
    MultipartReader& operator=(const MultipartReader&) = delete;

    /// Parse and stream one multipart request.
    mw::E<CardUpload> read(const httplib::ContentReader& content_reader);

private:
    std::filesystem::path card_storage_root_;
    std::filesystem::path staging_directory_;
};