import common
import maps.wikimap.stat.kpi.absolute_objects_counts_stat.lib.ft_processors as fp

from nile.api.v1 import (
    local,
    Record
)
import pytest


@pytest.fixture
def ft_sources(node, major_regions):
    return {
        'ft': local.StreamSource([
            Record(ft_id=1, ft_type_id=1401),   # urban-car-dealership
            Record(ft_id=2, ft_type_id=1401),   # urban-car-dealership
            Record(ft_id=3, ft_type_id=1402),   # urban-car-parts
            Record(ft_id=4, ft_type_id=1400),   # urban-car
            Record(ft_id=5, ft_type_id=11111),  # unknown ft_type_id
            Record(ft_id=6, ft_type_id=1),      # landmark
        ]),
        'ft_center': local.StreamSource([
            Record(ft_id=1, node_id='node_id1'),
            Record(ft_id=2, node_id='node_id1'),
            Record(ft_id=3, node_id='node_id2'),
            Record(ft_id=4, node_id='node_id2'),
            Record(ft_id=5, node_id='node_id2'),
            Record(ft_id=6, node_id='node_id2'),
        ]),
        'node': local.StreamSource(node),
        'major_regions': local.StreamSource(major_regions),
    }


def test_ft_region(statface_client, job, ft_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    ft_with_region = []
    job.local_run(
        sources=ft_sources,
        sinks={
            'ft_with_region': local.ListSink(ft_with_region),
        }
    )
    assert sorted(ft_with_region) == sorted([
        Record(ft_id=1, ft_type_id=1401,  node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(ft_id=2, ft_type_id=1401,  node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(ft_id=3, ft_type_id=1402,  node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=4, ft_type_id=1400,  node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=5, ft_type_id=11111, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=6, ft_type_id=1,     node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
    ])


def test_ft_with_categories(statface_client, job, ft_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    ft_with_categories = []
    job.local_run(
        sources=ft_sources,
        sinks={
            'ft_with_categories': local.ListSink(ft_with_categories),
        }
    )
    assert sorted(ft_with_categories) == sorted([
        Record(ft_id=1, category='urban-car-dealership', count=1, ft_type_id=1401,  node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(ft_id=2, category='urban-car-dealership', count=1, ft_type_id=1401,  node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(ft_id=3, category='urban-car-parts',      count=1, ft_type_id=1402,  node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=4, category='urban-car',            count=1, ft_type_id=1400,  node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=5, category='11111',                count=1, ft_type_id=11111, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(ft_id=6, category='landmark',             count=1, ft_type_id=1,     node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
    ])


def test_count_ft_type_supercategories_reducer():
    groups = [
        ('\t10000\t', [
            Record(category='urban-leisure-museum',     count=1,   region_tree='\t10000\t'),
            Record(category='urban-leisure-waterpark',  count=2,   region_tree='\t10000\t'),
            Record(category='urban-leisure',            count=4,   region_tree='\t10000\t'),
            Record(category='urban-playground',         count=8,   region_tree='\t10000\t'),
            Record(category='urban-entrance',           count=16,  region_tree='\t10000\t'),
            Record(category='urban-sport-ski',          count=32,  region_tree='\t10000\t'),
            Record(category='landmark',                 count=64,  region_tree='\t10000\t'),
        ]),
        ('\t10000\t159', [
            Record(category='urban-leisure-waterpark',  count=128,  region_tree='\t10000\t159'),
            Record(category='urban-playground',         count=256, region_tree='\t10000\t159'),
            Record(category='urban-entrance',           count=512, region_tree='\t10000\t159'),
        ]),
    ]
    assert sorted(list(fp.count_ft_type_supercategories_reducer(groups))) == sorted([
        Record(category='urban-leisure-museum',     count=1,   region_tree='\t10000\t'),
        Record(category='urban-leisure-waterpark',  count=2,   region_tree='\t10000\t'),
        Record(category='urban-leisure',            count=4,   region_tree='\t10000\t'),
        Record(category='urban-leisure all',        count=7,   region_tree='\t10000\t'),
        Record(category='urban-playground',         count=8,   region_tree='\t10000\t'),
        Record(category='urban-entrance',           count=16,  region_tree='\t10000\t'),
        Record(category='urban-sport-ski',          count=32,  region_tree='\t10000\t'),
        Record(category='urban-sport all',          count=32,  region_tree='\t10000\t'),
        Record(category='urban all',                count=63,  region_tree='\t10000\t'),
        Record(category='landmark',                 count=64,  region_tree='\t10000\t'),
        Record(category='landmark all',             count=64,  region_tree='\t10000\t'),

        Record(category='urban-leisure-waterpark',  count=128, region_tree='\t10000\t159'),
        Record(category='urban-leisure all',        count=128, region_tree='\t10000\t159'),
        Record(category='urban-playground',         count=256, region_tree='\t10000\t159'),
        Record(category='urban-entrance',           count=512, region_tree='\t10000\t159'),
        Record(category='urban all',                count=896, region_tree='\t10000\t159'),  # 512 + 256 + 128
    ])


def test_ft_with_supercategories(statface_client, job, ft_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    ft_with_supercategories = []
    job.local_run(
        sources=ft_sources,
        sinks={
            'ft_with_supercategories': local.ListSink(ft_with_supercategories),
        }
    )
    assert sorted(ft_with_supercategories) == sorted([
        Record(category='11111',                    count=1, region_tree='\t10000\t'),              # Земля
        Record(category='landmark',                 count=1, region_tree='\t10000\t'),              # Земля
        Record(category='landmark all',             count=1, region_tree='\t10000\t'),              # Земля
        Record(category='urban all',                count=2, region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='urban all',                count=2, region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='urban all',                count=4, region_tree='\t10000\t'),              # Земля
        Record(category='urban-car',                count=1, region_tree='\t10000\t'),              # Земля
        Record(category='urban-car all',            count=2, region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='urban-car all',            count=2, region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='urban-car all',            count=4, region_tree='\t10000\t'),              # Земля
        Record(category='urban-car-dealership',     count=2, region_tree='\t10000\t'),              # Земля
        Record(category='urban-car-dealership',     count=2, region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='urban-car-dealership',     count=2, region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='urban-car-parts',          count=1, region_tree='\t10000\t'),              # Земля
    ])


def test_result_ft_by_region(statface_client, job, ft_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    result_ft_by_region = []
    job.local_run(
        sources=ft_sources,
        sinks={
            'result_ft_by_region': local.ListSink(result_ft_by_region),
        }
    )

    assert sorted(result_ft_by_region) == sorted([
        Record(category='ft ft_type=urban-car-dealership', count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-car-dealership', count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban-car-dealership', count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=urban-car-parts',      count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-car',            count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-car all',        count=4, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-car all',        count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban-car all',        count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=urban all',            count=4, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban all',            count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban all',            count=2, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=11111',                count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=landmark',             count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=landmark all',         count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
    ])


@pytest.fixture
def ft_named_sources(node, major_regions):
    return {
        'ft': local.StreamSource([
            Record(ft_id=1, ft_type_id=553),    # hydro-river
            Record(ft_id=2, ft_type_id=554),    # hydro-river-small
            Record(ft_id=3, ft_type_id=509),    # hydro-glacier
            Record(ft_id=4, ft_type_id=1904),   # urban-entrance
            Record(ft_id=5, ft_type_id=402),    # vegetation-park
            Record(ft_id=6, ft_type_id=402),    # vegetation-park
            Record(ft_id=7, ft_type_id=401),    # vegetation (not named)
        ]),
        'ft_center': local.StreamSource([
            Record(ft_id=1, node_id='node_id2'),
            Record(ft_id=2, node_id='node_id2'),
            Record(ft_id=3, node_id='node_id2'),
            Record(ft_id=4, node_id='node_id1'),
            Record(ft_id=5, node_id='node_id1'),
            Record(ft_id=6, node_id='node_id2'),
        ]),
        'ft_nm': local.StreamSource([
            Record(ft_id=1, nm_id=1),
            Record(ft_id=2, nm_id=2),
            Record(ft_id=4, nm_id=3),
            Record(ft_id=5, nm_id=4),
            Record(ft_id=7, nm_id=5),
        ]),
        'ft_poi_attr': local.StreamSource([]),
        'ft_edge': local.StreamSource([
            Record(ft_id=1, edge_id=1),
            Record(ft_id=2, edge_id=1),
        ]),
        'ft_face': local.StreamSource([
            Record(ft_id=3, face_id=1),
        ]),
        'node': local.StreamSource(node),
        'major_regions': local.StreamSource(major_regions),
    }


def test_ft_with_named(statface_client, job, ft_named_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    ft_with_named = []
    job.local_run(
        sources=ft_named_sources,
        sinks={
            'ft_with_named': local.ListSink(ft_with_named),
        }
    )

    assert sorted(ft_with_named) == sorted([
        Record(category='hydro-river',       count=1, ft_id=1, ft_type_id=553,  named=True, nm_id=1, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(category='hydro-river-small', count=1, ft_id=2, ft_type_id=554,  named=True, nm_id=2, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(category='hydro-glacier',     count=1, ft_id=3, ft_type_id=509,  named=False,         node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(category='urban-entrance',    count=1, ft_id=4, ft_type_id=1904, named=True, nm_id=3, node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(category='vegetation-park',   count=1, ft_id=5, ft_type_id=402,  named=True, nm_id=4, node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(category='vegetation-park',   count=1, ft_id=6, ft_type_id=402,  named=False,         node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
    ])


def test_count_ft_by_name(statface_client, job, ft_named_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    counted_ft_by_named = []
    job.local_run(
        sources=ft_named_sources,
        sinks={
            'counted_ft_by_named': local.ListSink(counted_ft_by_named),
        }
    )

    assert sorted(counted_ft_by_named) == sorted([
        Record(category='ft ft_type=hydro all named=False',         count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro all named=True',          count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river all named=True',    count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river named=True',        count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river-small named=True',  count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-glacier named=False',     count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-entrance named=True',     count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-entrance named=True',     count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban-entrance named=True',     count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=vegetation-park named=False',   count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=vegetation-park named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=vegetation-park named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=vegetation-park named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
    ])


def test_ft_count(statface_client, job, ft_named_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    result_ft = []
    job.local_run(
        sources=ft_named_sources,
        sinks={
            'result_ft': local.ListSink(result_ft),
        }
    )

    assert sorted(result_ft) == sorted([
        Record(category='ft ft_type=hydro all',             count=3, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-glacier',         count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river',           count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river all',       count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=hydro-river-small',     count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=poi',                   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=poi',                   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=poi',                   count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban all',             count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban all',             count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban all',             count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=urban-entrance',        count=1, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=urban-entrance',        count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=urban-entrance',        count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=vegetation all',        count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=vegetation all',        count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=vegetation all',        count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля
        Record(category='ft ft_type=vegetation-park',       count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),         # Земля/Казахстан
        Record(category='ft ft_type=vegetation-park',       count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),  # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=vegetation-park',       count=2, fielddate='2019-01-01', region_tree='\t10000\t'),              # Земля

        Record(category='ft ft_type=hydro all named=False',        count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=hydro all named=True',         count=2, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=hydro-glacier named=False',    count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=hydro-river all named=True',   count=2, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=hydro-river named=True',       count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=hydro-river-small named=True', count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=urban-entrance named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=urban-entrance named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),          # Земля/Казахстан
        Record(category='ft ft_type=urban-entrance named=True',    count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),   # Земля/Казахстан/Алматинская область
        Record(category='ft ft_type=vegetation-park named=False',  count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=vegetation-park named=True',   count=1, fielddate='2019-01-01', region_tree='\t10000\t'),               # Земля
        Record(category='ft ft_type=vegetation-park named=True',   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),          # Земля/Казахстан
        Record(category='ft ft_type=vegetation-park named=True',   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),   # Земля/Казахстан/Алматинская область
    ])


def test_ft_named_supercategories_mapper():
    assert sorted(fp.add_ft_named_supercategories_mapper([
        Record(ft_type_id=1904, named=True),   # urban-entrance
        Record(ft_type_id=1904, named=False),  # urban-entrance
        Record(ft_type_id=501,  named=True),   # hydro-ocean
        Record(ft_type_id=501,  named=False),  # hydro-ocean
        Record(ft_type_id=553,  named=True),   # hydro-river
        Record(ft_type_id=553,  named=False),  # hydro-river
        Record(ft_type_id=559,  named=True),   # hydro-river-canal
        Record(ft_type_id=559,  named=False),  # hydro-river-canal
        Record(ft_type_id=402,  named=True),   # vegetation-park
        Record(ft_type_id=402,  named=False),  # vegetation-park
    ])) == sorted([
        Record(category='ft ft_type=urban-entrance named=True',     ft_type_id=1904, named=True),   # urban-entrance
        Record(category='ft ft_type=urban-entrance named=False',    ft_type_id=1904, named=False),  # urban-entrance
        Record(category='ft ft_type=hydro-ocean named=True',        ft_type_id=501,  named=True),   # hydro-ocean
        Record(category='ft ft_type=hydro-ocean named=False',       ft_type_id=501,  named=False),  # hydro-ocean
        Record(category='ft ft_type=hydro all named=True',          ft_type_id=501,  named=True),   # hydro-ocean
        Record(category='ft ft_type=hydro all named=False',         ft_type_id=501,  named=False),  # hydro-ocean
        Record(category='ft ft_type=hydro-river named=True',        ft_type_id=553,  named=True),   # hydro-river
        Record(category='ft ft_type=hydro-river named=False',       ft_type_id=553,  named=False),  # hydro-river
        Record(category='ft ft_type=hydro-river all named=True',    ft_type_id=553,  named=True),   # hydro-river
        Record(category='ft ft_type=hydro-river all named=False',   ft_type_id=553,  named=False),  # hydro-river
        Record(category='ft ft_type=hydro all named=True',          ft_type_id=553,  named=True),   # hydro-river
        Record(category='ft ft_type=hydro all named=False',         ft_type_id=553,  named=False),  # hydro-river
        Record(category='ft ft_type=hydro-river-canal named=True',  ft_type_id=559,  named=True),   # hydro-river-canal
        Record(category='ft ft_type=hydro-river-canal named=False', ft_type_id=559,  named=False),  # hydro-river-canal
        Record(category='ft ft_type=hydro-river all named=True',    ft_type_id=559,  named=True),   # hydro-river-canal
        Record(category='ft ft_type=hydro-river all named=False',   ft_type_id=559,  named=False),  # hydro-river-canal
        Record(category='ft ft_type=hydro all named=True',          ft_type_id=559,  named=True),   # hydro-river-canal
        Record(category='ft ft_type=hydro all named=False',         ft_type_id=559,  named=False),  # hydro-river-canal
        Record(category='ft ft_type=vegetation-park named=True',    ft_type_id=402,  named=True),   # vegetation-park
        Record(category='ft ft_type=vegetation-park named=False',   ft_type_id=402,  named=False),  # vegetation-park
    ])


def test_get_poi_categories():
    assert list(fp.get_poi_categories('1')) == []
    assert list(fp.get_poi_categories('hydro-river')) == []
    assert list(fp.get_poi_categories('landmark')) == ['poi-landmark', 'poi-landmark-culture', 'poi']
    assert list(fp.get_poi_categories('urban-sport-ski')) == ['poi-landmark', 'poi-landmark-sport', 'poi']
    assert list(fp.get_poi_categories('urban-bike-rental')) == ['poi']


def test_add_poi_categories_mapper():
    assert list(fp.add_poi_categories_mapper([
        Record(region_id=1, category='1'),
        Record(region_id=2, category='hydro-river'),
        Record(region_id=3, category='landmark'),
        Record(region_id=4, category='urban-sport-ski'),
        Record(region_id=4, category='urban-bike-rental'),
    ])) == [
        Record(region_id=3, category='ft ft_type=poi-landmark'),
        Record(region_id=3, category='ft ft_type=poi-landmark-culture'),
        Record(region_id=3, category='ft ft_type=poi'),

        Record(region_id=4, category='ft ft_type=poi-landmark'),
        Record(region_id=4, category='ft ft_type=poi-landmark-sport'),
        Record(region_id=4, category='ft ft_type=poi'),

        Record(region_id=4, category='ft ft_type=poi'),
    ]


@pytest.fixture
def ft_poi_sources(node, major_regions):
    return {
        'ft': local.StreamSource([
            Record(ft_id=1, ft_type_id=553),   # hydro-river, not poi ft_type
            Record(ft_id=2, ft_type_id=510),   # hydro-pool,  poi
            Record(ft_id=3, ft_type_id=1),     # landmark,    poi
            Record(ft_id=4, ft_type_id=1),     # landmark,    not poi: has edge
            Record(ft_id=5, ft_type_id=114),   # urban-religion-worship,  poi
            Record(ft_id=6, ft_type_id=113),   # urban-religion-buddhism, poi
            Record(ft_id=7, ft_type_id=1808),  # urban-leisure-monument,  not poi: has face
        ]),
        'ft_center': local.StreamSource([
            Record(ft_id=1, node_id='node_id2'),
            Record(ft_id=2, node_id='node_id2'),
            Record(ft_id=3, node_id='node_id2'),
            Record(ft_id=4, node_id='node_id1'),
            Record(ft_id=5, node_id='node_id1'),
            Record(ft_id=6, node_id='node_id2'),
            Record(ft_id=7, node_id='node_id2'),
        ]),
        'ft_edge': local.StreamSource([
            Record(ft_id=1, edge_id=1),
            Record(ft_id=4, edge_id=1),
        ]),
        'ft_face': local.StreamSource([
            Record(ft_id=7, face_id=1),
        ]),
        'node': local.StreamSource(node),
        'major_regions': local.StreamSource(major_regions),
    }


def test_filter_poi(statface_client, job, ft_poi_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    ft_only_poi = []
    job.local_run(
        sources=ft_poi_sources,
        sinks={
            'ft_only_poi': local.ListSink(ft_only_poi),
        }
    )
    assert sorted(ft_only_poi) == sorted([
        Record(category='hydro-pool',              count=1, ft_id=2, ft_type_id=510, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(category='landmark',                count=1, ft_id=3, ft_type_id=1,   node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
        Record(category='urban-religion-worship',  count=1, ft_id=5, ft_type_id=114, node_id='node_id1', region_id='116783', **common.POINT_SHAPE1),
        Record(category='urban-religion-buddhism', count=1, ft_id=6, ft_type_id=113, node_id='node_id2', region_id='116889', **common.POINT_SHAPE2),
    ])


def test_count_poi(statface_client, job, ft_poi_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    counted_ft_poi = []
    job.local_run(
        sources=ft_poi_sources,
        sinks={
            'counted_ft_poi': local.ListSink(counted_ft_poi),
        }
    )
    assert sorted(counted_ft_poi) == sorted([
        Record(category='ft ft_type=poi',                   count=4, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft ft_type=poi',                   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft ft_type=poi',                   count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),

        Record(category='ft ft_type=poi-landmark',          count=3, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft ft_type=poi-landmark',          count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft ft_type=poi-landmark',          count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),

        Record(category='ft ft_type=poi-landmark-culture',  count=1, fielddate='2019-01-01', region_tree='\t10000\t'),

        Record(category='ft ft_type=poi-landmark-religion', count=2, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft ft_type=poi-landmark-religion', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft ft_type=poi-landmark-religion', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),
    ])


@pytest.fixture
def ft_poi_position_quality_sources(node, major_regions):
    return {
        'ft': local.StreamSource([
            Record(ft_id=1, ft_type_id=510),   # hydro-pool
            Record(ft_id=2, ft_type_id=1),     # landmark
            Record(ft_id=3, ft_type_id=114),   # urban-religion-worship
            Record(ft_id=4, ft_type_id=113),   # urban-religion-buddhism
            Record(ft_id=5, ft_type_id=113),   # urban-religion-buddhism
            Record(ft_id=6, ft_type_id=553),   # hydro-river, not poi ft_type
            Record(ft_id=7, ft_type_id=1),     # landmark, not poi: has edge
            Record(ft_id=8, ft_type_id=1808),  # urban-leisure-monument, not poi: has face
        ]),
        'ft_poi_attr': local.StreamSource([
            Record(ft_id=1, position_quality=5),
            Record(ft_id=2, position_quality=4),
            Record(ft_id=3, position_quality=0),
            Record(ft_id=4, position_quality=4),
            Record(ft_id=5, position_quality=0),
        ]),
        'ft_center': local.StreamSource([
            Record(ft_id=1, node_id='node_id1'),
            Record(ft_id=2, node_id='node_id1'),
            Record(ft_id=3, node_id='node_id1'),
            Record(ft_id=4, node_id='node_id2'),
            Record(ft_id=5, node_id='node_id2'),
            Record(ft_id=6, node_id='node_id1'),
            Record(ft_id=7, node_id='node_id1'),
            Record(ft_id=8, node_id='node_id1'),
        ]),
        'ft_edge': local.StreamSource([
            Record(ft_id=6, edge_id=1),
            Record(ft_id=7, edge_id=1),
        ]),
        'ft_face': local.StreamSource([
            Record(ft_id=8, face_id=1),
        ]),
        'node': local.StreamSource(node),
        'major_regions': local.StreamSource(major_regions),
    }


def test_count_poi_by_position_quality(statface_client, job, ft_poi_position_quality_sources):
    job = common.make_count_job(statface_client, job, ['ft'])

    counted_ft_poi_by_position_quality = []
    job.local_run(
        sources=ft_poi_position_quality_sources,
        sinks={
            'counted_ft_poi_by_position_quality': local.ListSink(counted_ft_poi_by_position_quality),
        }
    )
    assert sorted(counted_ft_poi_by_position_quality) == sorted([
        Record(category='ft position_quality=precise', count=2, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft position_quality=precise', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft position_quality=precise', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),

        Record(category='ft position_quality=user', count=1, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft position_quality=user', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft position_quality=user', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),

        Record(category='ft position_quality=not_set', count=2, fielddate='2019-01-01', region_tree='\t10000\t'),
        Record(category='ft position_quality=not_set', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t'),
        Record(category='ft position_quality=not_set', count=1, fielddate='2019-01-01', region_tree='\t10000\t159\t29406\t'),
    ])
