#pragma once

#include "common.h"
#include <maps/wikimap/mapspro/libs/acl/include/aclgateway.h>
#include <maps/libs/json/include/value.h>

#include <optional>
#include <string>
#include <vector>

namespace maps::wiki::aclsrv {

struct PoliciesUpdateData
{
    std::vector<PolicyData> policiesData;
    std::vector<GroupData> groupsData;
};

struct UserUpdateData
{
    acl::ID id;
    std::optional<acl::UID> uid;
    std::optional<acl::User::Status> status;
    std::optional<acl::User::DeleteReason> deleteReason;
    std::optional<std::string> login;
    std::optional<PoliciesUpdateData> policies;
    std::optional<std::string> displayName;

    explicit UserUpdateData(const json::Value& jsonUserObject);

    static std::vector<UserUpdateData> parseData(const std::string& str);

    bool isSelfRegistration(acl::UID authorUid) const;
    bool isSelfUpdate(acl::UID authorUid, acl::ACLGateway& gw) const;
};

struct UsersPoliciesUpdateData
{
    static UsersPoliciesUpdateData parseData(const std::string& jsonStr);
    std::set<acl::UID> uids;
    PoliciesUpdateData policiesToRemove;
    PoliciesUpdateData policiesToAdd;
};

acl::ID saveUser(
    acl::ACLGateway& gw,
    const UserUpdateData& userUpdateData,
    acl::UID authorUid,
    FromTest fromTest = FromTest::False);

void saveUsersPolicies(
    acl::ACLGateway& gw,
    const UsersPoliciesUpdateData& usersPoliciesUpdateData,
    acl::UID authorUid);

} // namespace maps::wiki::aclsrv
