from maps.wikimap.stat.libs.geobase_regions import (
    FILES as GEOBASE_FILES,
    GEOBASE_JOB_MEMORY_LIMIT_MB,
    lon_lat_bbox_to_region_id,
)
from maps.wikimap.stat.libs.common.lib import dates as d

from nile.api.v1 import (
    extractors as ne,
    filters as nf,
    datetime as nd,
)

import os
import datetime as dt


MODERATION_LOG_TABLES = 'nmaps-moderation-log/1d'
USERS_DUMP_LOG_TABLES = 'nmaps-users-dump-log/1d'

EDITS_LOG_TABLES = 'nmaps-edits-log/1d/'


def moderation_period(isodate):
    start_date = nd.Datetime.from_iso(isodate).date()
    today = nd.Datetime.from_date(dt.date.today()).date()
    end_date = start_date + dt.timedelta(days=d.MODERATION_MAX_DELAY)
    if end_date > today:
        end_date = today

    last_date = end_date - dt.timedelta(days=1)
    return '{' + start_date.isoformat() + '..' + last_date.isoformat() + '}'


def make_job(job, date, logs_path, analytics_path, results_path):
    users_dump_log = job.table(
        os.path.join(logs_path, USERS_DUMP_LOG_TABLES, date)
    ).label(
        'users_dump_log'
    )

    users_dump_log_closed = users_dump_log.project(
        moderation_closed_status='moderation_status',
        moderation_closed_puid='puid'
    )

    users_dump_log_resolved = users_dump_log.project(
        moderation_resolved_status='moderation_status',
        moderation_resolved_puid='puid'
    )

    edits_log = job.table(
        os.path.join(logs_path, EDITS_LOG_TABLES, date)
    ).label('edits_log')

    geotagged_edits_log = edits_log.project(
        ne.all(),
        region_id=ne.custom(lambda bbox: str(lon_lat_bbox_to_region_id(bbox)), 'geom'),
        files=GEOBASE_FILES,
        memory_limit=GEOBASE_JOB_MEMORY_LIMIT_MB,
    ).label('geotagged_edits_log')

    moderation_log = job.table(
        os.path.join(logs_path, MODERATION_LOG_TABLES, moderation_period(date))
    ).label(
        'moderation_log'
    )

    moderation_create_log = moderation_log.filter(
        nf.equals('task_action', 'created')
    ).project(
        object_id='object_id',
        commit_id='commit_id',
        moderation_task_id='task_id',
    )

    moderation_resolved_log = moderation_log.filter(
        nf.equals('task_action', 'resolved')
    ).project(
        moderation_task_id='task_id',

        moderation_resolved_resolution='resolution',
        moderation_resolved_time='iso_eventtime',
        moderation_resolved_puid='puid',
    ).join(
        users_dump_log_resolved,
        by=('moderation_resolved_puid'),
        assume_unique_right=True,
    )

    moderation_closed_log = moderation_log.filter(
        nf.equals('task_action', 'closed')
    ).project(
        moderation_task_id='task_id',

        moderation_revert_reason='revert_reason',

        moderation_closed_resolution='resolution',
        moderation_closed_time='iso_eventtime',
        moderation_closed_puid='puid',
    ).join(
        users_dump_log_closed,
        by=('moderation_closed_puid'),
        assume_unique_right=True,
    )

    moderation_joined_log = moderation_create_log.join(
        moderation_resolved_log,
        by=('moderation_task_id'),
        type='left',
        assume_unique=True,
    ).join(
        moderation_closed_log,
        by=('moderation_task_id'),
        type='left',
        assume_unique=True,
    ).label('joined_moderation')

    moderation_edits_log = geotagged_edits_log.join(
        moderation_joined_log,
        by=('commit_id', 'object_id'),
        type='left',
        assume_unique=True,
    ).join(
        users_dump_log,
        by=('puid'),
        assume_unique_right=True,
    ).label('result')

    moderation_edits_log.put(os.path.join(results_path, date))

    return job
