#include <maps/wikimap/ugc/backoffice/src/gdpr/lib/dbqueries.h>

#include <maps/wikimap/ugc/libs/common/constants.h>
#include <maps/wikimap/ugc/libs/test_helpers/db_fixture.h>
#include <maps/wikimap/ugc/libs/test_helpers/test_dbpools.h>
#include <maps/wikimap/ugc/libs/test_helpers/takeout.h>

#include <maps/wikimap/mapspro/libs/query_builder/include/insert_query.h>
#include <maps/wikimap/mapspro/libs/query_builder/include/select_query.h>
#include <maps/wikimap/mapspro/libs/query_builder/include/delete_query.h>

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

#include <library/cpp/testing/unittest/env.h>
#include <library/cpp/testing/unittest/registar.h>

namespace maps::wiki::ugc::backoffice::gdpr::tests {

Y_UNIT_TEST_SUITE(test_db_queries)
{

Y_UNIT_TEST(load_incomplete_gdpr_requests)
{
    ugc::tests::TestDbPools db;

    Uid uidNew{123};
    Uid uidCompleted{456};

    ugc::gdpr::RequestId requestIdNew{"request_new"};
    ugc::gdpr::RequestId requestIdCompleted{"request_completed"};

    {
        auto txn = db.pool().masterWriteableTransaction();

        ugc::tests::putTakeout(*txn, uidNew, requestIdNew);
        ugc::tests::putTakeout(*txn, uidCompleted, requestIdCompleted, maps::chrono::TimePoint::clock::now());

        txn->commit();
    }


    auto result = loadIncompleteTakeouts(db.pool());

    UNIT_ASSERT_VALUES_EQUAL(result.size(), 1);
    UNIT_ASSERT_VALUES_EQUAL(result[0].uid.value(), uidNew.value());
    UNIT_ASSERT_VALUES_EQUAL(result[0].requestId.value(), requestIdNew.value());

    {
        auto txn = db.pool().masterWriteableTransaction();

        maps::wiki::query_builder::DeleteQuery(
            tables::GDPR_TAKEOUT,
            query_builder::WhereConditions().notNull(columns::UID)
        ).exec(*txn);

        txn->commit();
    }
}

Y_UNIT_TEST(set_request_completed)
{
    ugc::tests::TestDbPools db;

    ugc::gdpr::TakeoutId takeoutId;
    Uid uid{123};
    ugc::gdpr::RequestId requestId{"request_id"};

    {
        auto txn = db.pool().masterWriteableTransaction();
        takeoutId = ugc::tests::putTakeout(*txn, uid, requestId);
        txn->commit();
    }

    setTakeoutCompleted(db.pool(), takeoutId, false);

    {
        auto txn = db.pool().masterReadOnlyTransaction();

        auto result = maps::wiki::query_builder::SelectQuery(
            tables::GDPR_TAKEOUT,
            maps::wiki::query_builder::WhereConditions()
                .append(columns::TAKEOUT_ID, std::to_string(takeoutId.value()))
        ).exec(*txn);

        UNIT_ASSERT_VALUES_EQUAL(result.size(), 1);
        UNIT_ASSERT_VALUES_EQUAL(result[0][columns::UID].as<uint64_t>(), uid.value());
        UNIT_ASSERT(!result[0][columns::COMPLETED_AT].is_null());
    }

    {
        auto txn = db.pool().masterWriteableTransaction();

        maps::wiki::query_builder::DeleteQuery(
            tables::GDPR_TAKEOUT,
            query_builder::WhereConditions().notNull(columns::UID)
        ).exec(*txn);

        txn->commit();
    }
}

Y_UNIT_TEST(remove_table_user_data)
{
    ugc::tests::TestDbPools db;

    Uid uid{123};

    {
        auto txn = db.pool().masterWriteableTransaction();

        maps::wiki::query_builder::InsertQuery(tables::ASSIGNMENT)
            .append(columns::UID, std::to_string(uid.value()))
            .appendQuoted(columns::TASK_ID, "task_id")
            .append(columns::METADATA_ID, "0")
            .appendQuoted(columns::STATUS, std::string{toString(ugc::AssignmentStatus::Active)})
            .exec(*txn);

        txn->commit();
    }

    {
        auto txn = db.pool().masterReadOnlyTransaction();

        auto initial = maps::wiki::query_builder::SelectQuery(
            tables::ASSIGNMENT,
            maps::wiki::query_builder::WhereConditions()
                .append(columns::UID, std::to_string(uid.value()))
        ).exec(*txn);

        UNIT_ASSERT_VALUES_EQUAL(initial.size(), 1);
    }

    {
        auto txn = db.pool().masterWriteableTransaction();
        removeTableUserData(*txn, tables::ASSIGNMENT, uid, maps::chrono::TimePoint::clock::now());
        txn->commit();
    }

    {
        auto txn = db.pool().masterReadOnlyTransaction();

        auto result = maps::wiki::query_builder::SelectQuery(
            tables::ASSIGNMENT,
            maps::wiki::query_builder::WhereConditions()
                .append(columns::UID, std::to_string(uid.value()))
        ).exec(*txn);

        UNIT_ASSERT_VALUES_EQUAL(result.size(), 0);
    }

    {
        auto txn = db.pool().masterWriteableTransaction();

        maps::wiki::query_builder::DeleteQuery(
            tables::GDPR_TAKEOUT,
            query_builder::WhereConditions().notNull(columns::UID)
        ).exec(*txn);

        txn->commit();
    }
}

}

} // namespace maps::wiki::ugc::backoffice::gdpr::tests
