#include "suspicious_users.h"

#include <maps/libs/chrono/include/time_point.h>

#include <string>

namespace maps::wiki::social::suspicious_users {

namespace {

const chrono::Days SUSPICIOUS_CREATED_OR_UNBANNED_TIME_THRESHOLD(1);

bool isUserSuspicious(const std::string& userCreatedOrUnbannedAt) {
    return
        std::chrono::system_clock::now() - chrono::parseSqlDateTime(userCreatedOrUnbannedAt) <
        SUSPICIOUS_CREATED_OR_UNBANNED_TIME_THRESHOLD;
}

} // namespace


void removeOld(pqxx::transaction_base& txn, chrono::Days olderThan)
{
    auto olderThanInterval = "interval '" + std::to_string(olderThan.count()) + " days'";
    txn.exec(
        "DELETE FROM social.suspicious_users "
        "WHERE uid IN "
        "("
        "  SELECT uid"
        "  FROM social.suspicious_users"
        "  WHERE registered_or_unbanned_at < NOW() - " + olderThanInterval +
        "  ORDER BY uid"
        "  FOR UPDATE"
        ")"
    );
}


void onTaskCreated(pqxx::transaction_base& txn, TUid uid, const std::string& userCreatedOrUnbannedAt)
{
    if (!isUserSuspicious(userCreatedOrUnbannedAt)) {
        return;
    }

    txn.exec(
        "INSERT INTO social.suspicious_users "
        "VALUES (" + std::to_string(uid) + ", " + txn.quote(userCreatedOrUnbannedAt) + ") "
        "ON CONFLICT ON CONSTRAINT suspicious_users_pkey "
        "DO UPDATE "
        "SET"
        "  registered_or_unbanned_at = EXCLUDED.registered_or_unbanned_at,"
        "  last_commit_at = NOW(),"
        "  first_commit_at = CASE"
        "    WHEN (social.suspicious_users.registered_or_unbanned_at = EXCLUDED.registered_or_unbanned_at)"
        "    THEN EXCLUDED.registered_or_unbanned_at"
        "    ELSE NOW()"
        "  END,"
        "  changes_0_30_sec = CASE"
        "    WHEN (NOW() - social.suspicious_users.last_commit_at < interval '30 sec')"
        "    THEN social.suspicious_users.changes_0_30_sec + 1"
        "    ELSE social.suspicious_users.changes_0_30_sec"
        "  END"
    );
}

} // namespace maps::wiki::social::suspicious_users
