#include "tasks_acquire_blocking.h"

#include "maps/wikimap/mapspro/services/editor/src/acl_utils.h"
#include "maps/wikimap/mapspro/services/editor/src/branch_helpers.h"
#include "maps/wikimap/mapspro/services/editor/src/configs/config.h"
#include "maps/wikimap/mapspro/services/editor/src/exception.h"
#include "maps/wikimap/mapspro/services/editor/src/check_permissions.h"
#include <maps/wikimap/mapspro/services/editor/src/social_utils.h>

#include "helpers.h"

#include <maps/wikimap/mapspro/libs/acl_utils/include/moderation.h>
#include <maps/wikimap/mapspro/libs/revision_meta/include/blocking_commits.h>
#include <maps/wikimap/mapspro/libs/acl/include/aclgateway.h>
#include <yandex/maps/wiki/social/gateway.h>

namespace maps::wiki {

namespace {

const std::string TASK_METHOD_NAME = "SocialModerationTasksAcquireBlocking";

} // namespace

SocialModerationTasksAcquireBlocking::Request::Request(
    TUid uid,
    TCommitId commitId
)
    : user(uid)
    , commitId(commitId)
{
    CHECK_REQUEST_PARAM(user);
    CHECK_REQUEST_PARAM(commitId);
}

std::string
SocialModerationTasksAcquireBlocking::Request::dump() const
{
    std::stringstream ss;
    ss << " uid: " << user
       << " commit: " << commitId;
    return ss.str();
}


SocialModerationTasksAcquireBlocking::SocialModerationTasksAcquireBlocking(
    const ObserverCollection&,
    const Request& request,
    taskutils::TaskID asyncTaskID
)
    : controller::BaseController<SocialModerationTasksAcquireBlocking>(BOOST_CURRENT_FUNCTION, asyncTaskID)
    , request_(request)
{}

std::string
SocialModerationTasksAcquireBlocking::printRequest() const
{
    return request_.dump();
}

void
SocialModerationTasksAcquireBlocking::control()
{
    auto branchCtx = CheckedTrunkBranchContextFacade().acquireWrite();

    auto permissionsChecker = CheckPermissions(request_.user, branchCtx.txnCore());
    permissionsChecker.checkPermissionsToBlockingTasks();

    social::Gateway socialGw(branchCtx.txnSocial());

    social::EventFilter eventFilter;
    eventFilter.commitIds(
        revision_meta::getBlockingCommits(
            branchCtx.txnCore(),
            request_.commitId,
            socialGw.getAllActiveEditTasksCommitIds()
        )
    );

    if (eventFilter.commitIds()->empty()) {
        return;
    }

    eventFilter.eventType(social::EventType::Edit);

    const auto NO_LIMIT = std::nullopt;
    result_->tasks =
        socialGw
        .moderationConsole(request_.user)
        .acquireTasks(
            eventFilter, NO_LIMIT, social::TasksOrder::NewestFirst, cfg()->moderationTimeIntervals());

    result_->alertsByTaskId = fillAlertsByTaskId(
        result_->tasks, socialGw, permissionsChecker);
    result_->token = branchCtx.commit();
}

const std::string&
SocialModerationTasksAcquireBlocking::taskName()
{
    return TASK_METHOD_NAME;
}

} // namespace maps::wiki
