BareGit
#pragma once

#include <cstdint>
#include <string>
#include <vector>

#include <mw/error.hpp>

#include "authorization.h"
#include "data.h"
#include "markdown_renderer.h"

/// A game-definition validation failure addressable by an editor control.
struct GameDefinitionValidationError
{
    /// Logical form field containing the invalid definition value.
    std::string field_name;

    /// Safe user-facing validation message.
    std::string msg;
};

/// Validate and coordinate database-defined game mutations.
class GameService
{
public:
    /// Construct a game service over the application persistence boundary.
    explicit GameService(DataSourceInterface& data_source);

    /// Create a game and return its permanent short name.
    mw::E<std::string> createGame(
        std::int64_t actor_user_id,
        std::string short_name,
        std::string display_name,
        std::string description,
        GameVisibility visibility);

    /// Update a game's mutable presentation metadata.
    mw::E<void> updateGame(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t expected_revision,
        std::string display_name,
        std::string description,
        GameVisibility visibility);

    /// Delete a game only when it has never issued a card number.
    mw::E<void> removeGame(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t expected_revision);

    /// Add a custom field and return its internal identity.
    mw::E<std::int64_t> createField(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t expected_revision,
        std::string key,
        std::string label,
        GameFieldType type,
        std::vector<std::string> choices);

    /// Update a field label and its complete ordered choice list.
    mw::E<void> updateField(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t field_id,
        std::int64_t expected_revision,
        std::string label,
        std::vector<std::string> choices);

    /// Delete an unused custom field.
    mw::E<void> removeField(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t field_id,
        std::int64_t expected_revision);

    /// Save a complete ordering of a game's custom fields.
    mw::E<void> reorderFields(
        std::int64_t actor_user_id,
        const std::string& short_name,
        std::int64_t expected_revision,
        const std::vector<std::int64_t>& field_ids);

private:
    DataSourceInterface& data_source_;
    AuthorizationService authorization_;
    MarkdownRenderer markdown_renderer_;
};