from maps.wikimap.stat.assessment.report.lib import moderation

from maps.wikimap.stat.libs import nile_ut

from nile.api.v1 import Record
from nile.drivers.common.progress import CommandFailedError

import pytest


def test_should_add_task_id():
    result = nile_ut.yt_run(
        moderation._add_task_id,
        assessed_tasks=nile_ut.Table([
            Record(action_by=1, action=b'resolve', graded_by=11, grade=b'grade 1', geom=b'geom 1', category_id=b'category 1'),
            Record(action_by=2, action=b'close',   graded_by=12, grade=b'grade 2', geom=b'geom 2', category_id=b'category 2'),
            Record(action_by=3, action=b'resolve', graded_by=13, grade=b'grade 3', geom=b'geom 3', category_id=None),
            Record(action_by=4, action=b'close',   graded_by=14, grade=b'grade 4', geom=b'geom 4', category_id=None),
        ])
    )

    assert sorted([
        Record(action_by=1, action=b'resolve', graded_by=11, grade=b'grade 1', geom=b'geom 1', task_id=b'moderation/resolved/category 1'),
        Record(action_by=2, action=b'close',   graded_by=12, grade=b'grade 2', geom=b'geom 2', task_id=b'moderation/closed/category 2'),
        Record(action_by=3, action=b'resolve', graded_by=13, grade=b'grade 3', geom=b'geom 3', task_id=b'moderation/resolved/common'),
        Record(action_by=4, action=b'close',   graded_by=14, grade=b'grade 4', geom=b'geom 4', task_id=b'moderation/closed/common'),
    ]) == sorted(result)


def test_should_fail_adding_task_id_for_wrong_action():
    with pytest.raises(CommandFailedError):
        nile_ut.yt_run(
            moderation._add_task_id,
            assessed_tasks=nile_ut.Table([
                Record(action_by=1, action=b'unknown', graded_by=1, grade=b'grade', geom=b'geom', category_id=b'category'),
            ])
        )

    with pytest.raises(CommandFailedError):
        nile_ut.yt_run(
            moderation._add_task_id,
            assessed_tasks=nile_ut.Table([
                Record(action_by=1, action=None, graded_by=1, grade=b'grade', geom=b'geom', category_id=b'category'),
            ])
        )


def test_should_get_paid_tasks():
    result = nile_ut.yt_run(
        moderation._get_paid_tasks,
        moderation_log=nile_ut.Table([
            Record(puid=1, task_id=b'moderation/resolved/category_1', lat_min=11, lon_min=12, lat_max=13, lon_max=14, test_column=1),
            Record(puid=2, task_id=b'moderation/closed/category_2',   lat_min=21, lon_min=22, lat_max=23, lon_max=24, test_column=2),
        ])
    )

    assert sorted([
        Record(lat=12, lon=13, task_id=b'moderation/resolved/category_1', action_by=1, action=b'resolve'),
        Record(lat=22, lon=23, task_id=b'moderation/closed/category_2',   action_by=2, action=b'close'),
    ]) == sorted(result)


def test_should_fail_on_getting_paid_tasks_for_wrong_task_id():
    with pytest.raises(CommandFailedError):
        nile_ut.yt_run(
            moderation._get_paid_tasks,
            moderation_log=nile_ut.Table([
                Record(puid=1, task_id=b'moderation/unknown_action/category', lat_min=1, lon_min=2, lat_max=3, lon_max=4),
            ])
        )

    with pytest.raises(CommandFailedError):
        nile_ut.yt_run(
            moderation._get_paid_tasks,
            moderation_log=nile_ut.Table([
                Record(puid=1, task_id=b'unknown_prefix/resolved/category', lat_min=1, lon_min=2, lat_max=3, lon_max=4),
            ])
        )


def test_should_get_tasks(geom_fixture):
    result = nile_ut.yt_run(
        moderation.get_tasks,
        nile_ut.Job(),
        commit_event_table=nile_ut.Table([
            Record(event_id=1, bounds_geom=b'11, 12', primary_object_category_id=b'category 1'),
            Record(event_id=2, bounds_geom=b'21, 22', primary_object_category_id=b'category 2'),
            Record(event_id=3, bounds_geom=b'31, 32', primary_object_category_id=b'category 3'),
        ]),
        latest_grades=nile_ut.Table([
            Record(entity_id=b'1', action_by=1,  action=b'resolve', graded_by=101, grade=b'grade 1'),
            Record(entity_id=b'2', action_by=21, action=b'close',   graded_by=121, grade=b'grade 21'),
            Record(entity_id=b'2', action_by=22, action=b'resolve', graded_by=122, grade=b'grade 22'),
            Record(entity_id=b'4', action_by=4,  action=b'close',   graded_by=104, grade=b'grade 4'),
        ]),
        moderation_log=nile_ut.Table([
            Record(puid=5, task_id=b'moderation/resolved/category 5', lat_min=51, lon_min=52, lat_max=53, lon_max=54),
            Record(puid=6, task_id=b'moderation/closed/category 6',   lat_min=61, lon_min=62, lat_max=63, lon_max=64),
        ])
    )

    assert sorted([
        Record(lat=11.0, lon=12.0, task_id=b'moderation/resolved/category 1', action_by=1,  action=b'resolve', graded_by=101,  grade=b'grade 1'),
        Record(lat=21.0, lon=22.0, task_id=b'moderation/closed/category 2',   action_by=21, action=b'close',   graded_by=121,  grade=b'grade 21'),
        Record(lat=21.0, lon=22.0, task_id=b'moderation/resolved/category 2', action_by=22, action=b'resolve', graded_by=122,  grade=b'grade 22'),
        Record(lat=52.0, lon=53.0, task_id=b'moderation/resolved/category 5', action_by=5,  action=b'resolve', graded_by=None, grade=None),
        Record(lat=62.0, lon=63.0, task_id=b'moderation/closed/category 6',   action_by=6,  action=b'close',   graded_by=None, grade=None),
    ]) == sorted(result)
