from cyson import UInt
from yt.wrapper import ypath_join
from nile.api.v1 import (
    files,
    Record
)
from maps.wikimap.stat.tasks_payment.dictionaries.libs.users import normalize_yalogin
from qb2.api.v1 import typing


USERS_DUMP_TABLES = 'nmaps-users-dump-log/1d'
STAFF_DUMP_PATH = 'tasks_payment/dictionaries/staff_dump'

RESULT_PATH = 'tasks_payment/dictionaries/linked_accounts'
RESULT_SCHEMA = {
    'puid': typing.UInt64,
    'login': typing.String,
    'staff_uid': typing.UInt64,
    'staff_login': typing.String,
    'is_primary_link': typing.Bool,
}


def _get_staff_dump(records):
    staff_dump = {}
    for record in records:
        for rank, yalogin in enumerate(record['nmaps_logins']):
            staff_dump[yalogin] = {
                'login':           yalogin,
                'staff_login':     record['login'],
                'staff_uid':       UInt(record['uid']),
                'is_primary_link': rank == 0,
            }
    return staff_dump


def _persons_mapper(records, **options):
    staff_dump = _get_staff_dump(options['file_streams']['staff_dump'])
    for record in records:
        employee = staff_dump.get(normalize_yalogin(record['um_login']))
        if employee is not None:
            yield Record(puid=UInt(record['puid']), **employee)


def make_job(job, isodate, logs_path, analytics_path, results_path):
    users_dump = job.table(
        ypath_join(logs_path, USERS_DUMP_TABLES, isodate)
    ).label('users_dump')
    staff_dump = job.table(
        ypath_join(analytics_path, STAFF_DUMP_PATH, isodate)
    ).label('staff_dump')

    result = users_dump.map(
        _persons_mapper,
        files=[files.StreamFile(staff_dump, 'staff_dump')]
    ).label('result')

    result.put(results_path, schema=RESULT_SCHEMA, ensure_optional=False)

    return job
