# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-11 04:59
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations

from pootle.core.batch import Batch


# Old types
REVERT_TYPE = 2
SUGG_ACCEPT_TYPE = 3
SUGG_ADD_TYPE = 8
SUGG_REJECT_TYPE = 9
UNIT_CREATE_TYPE = 10

# Fields
TARGET_FIELD = 2
STATE_FIELD = 3

# Remaining types
MUTE_TYPE = 6
UNMUTE_TYPE = 7

NEW_MUTED = 0
NEW_UNMUTED = 1
NEW_CHECK_FIELD = 5
NEW_WEB_TYPE = 1

# 2, 3, 8, 9, 10
OLD_TYPES = [
    REVERT_TYPE,
    SUGG_ACCEPT_TYPE,
    SUGG_ADD_TYPE,
    SUGG_REJECT_TYPE,
    UNIT_CREATE_TYPE]


CLEANUP_STORE_DATA_SQL = (
    "UPDATE `pootle_store_data` "
    " INNER JOIN `pootle_app_submission` "
    "  ON `pootle_app_submission`.`id` = `pootle_store_data`.`last_submission_id` "
    " SET `last_submission_id` = NULL"
    " WHERE `pootle_app_submission`.`type` in (%s)")

CLEANUP_TP_DATA_SQL = (
    "UPDATE `pootle_tp_data` "
    " INNER JOIN `pootle_app_submission` "
    "  ON `pootle_app_submission`.`id` = `pootle_tp_data`.`last_submission_id` "
    " SET `last_submission_id` = NULL"
    " WHERE `pootle_app_submission`.`type` in (%s)")

CLEANUP_SQL = (
    "DELETE FROM `pootle_app_submission` "
    " WHERE (`unit_id` IS NULL"
    "        OR `pootle_app_submission`.`type` in (%s))")


def cleanup_subs_with_sql(schema_editor):
    cursor = schema_editor.connection.cursor()
    _old_types = ", ".join(str(t) for t in OLD_TYPES)
    # remove any fks to submissions that are to be deleted
    cursor.execute(CLEANUP_STORE_DATA_SQL % _old_types)
    cursor.execute(CLEANUP_TP_DATA_SQL % _old_types)
    cursor.execute(CLEANUP_SQL % _old_types)


def cleanup_subs_with_orm(apps):
    subs = apps.get_model("pootle_statistics.Submission").objects.all()
    to_delete = (
        subs.filter(unit_id__isnull=True)
        | subs.filter(type__in=OLD_TYPES))
    to_delete.delete()


def cleanup_subs(apps, schema_editor):
    if schema_editor.connection.vendor == "mysql" and settings.POOTLE_SQL_MIGRATIONS:
        cleanup_subs_with_sql(schema_editor)
    else:
        cleanup_subs_with_orm(apps)


def _cleanup_accept_suggestion_subs(apps):
    # state/target changes that happened from suggestion had type=3,
    # and state change subs did not have their suggestion associated
    # They also credited the reviewer not the submitter
    # we need to:
    # - associate any state change subs with relevant suggestions
    # - set the suggester as submitter for all type=3 submissions
    # - update type to WEB for all type=3 subs that have suggestions
    # any remaining submissions of this type are likely dupes and will be deleted
    Submission = apps.get_model("pootle_statistics.Submission")
    subs = Submission.objects.all()
    suggestions = apps.get_model("pootle_store.Suggestion").objects

    # assoc state change subs with suggestions and update the sub
    to_update = []
    accepted_suggestions = suggestions.filter(state__name="accepted").values(
        "review_time", "pk", "unit_id", "reviewer_id", "user_id")
    accept_sugg_state_subs = subs.filter(
        type=SUGG_ACCEPT_TYPE).filter(field=STATE_FIELD)
    accept_subs_for_update = accept_sugg_state_subs.select_related(
        "suggestion").only("id", "type", "submitter_id", "suggestion_id")
    for suggestion in accepted_suggestions.iterator():
        suggestion["submitter_id"] = suggestion["reviewer_id"]
        suggestion["creation_time"] = suggestion["review_time"]
        suggestion_id = suggestion["pk"]
        suggestion_user = suggestion["user_id"]
        del suggestion["review_time"]
        del suggestion["reviewer_id"]
        del suggestion["pk"]
        del suggestion["user_id"]
        matching_sub = accept_subs_for_update.filter(**suggestion).first()
        if matching_sub:
            matching_sub.type = NEW_WEB_TYPE
            matching_sub.suggestion_id = suggestion_id
            matching_sub.submitter_id = suggestion_user
            to_update.append(matching_sub)
    if to_update:
        Batch(Submission.objects, batch_size=5000).update(
            to_update,
            update_fields=["type", "suggestion_id", "submitter_id"],
            reduces=False)

    # all remaining valid sugg_accept subs should be field=target and have a suggestion
    to_update = []
    accept_sugg_subs = subs.filter(type=SUGG_ACCEPT_TYPE).filter(field=TARGET_FIELD).exclude(suggestion__isnull=True)
    accept_subs_for_update = accept_sugg_subs.select_related(
        "suggestion").only("id", "type", "submitter_id", "suggestion__user_id")
    for sub in accept_subs_for_update.iterator():
        sub.submitter_id = sub.suggestion.user_id
        sub.type = NEW_WEB_TYPE
        to_update.append(sub)
    if to_update:
        Batch(Submission.objects, batch_size=5000).update(
            to_update,
            update_fields=["type", "submitter_id"],
            reduces=False)


def _cleanup_checks(apps):
    subs = apps.get_model("pootle_statistics.Submission").objects
    subs.filter(type=MUTE_TYPE).update(
        old_value=NEW_UNMUTED,
        new_value=NEW_MUTED,
        type=NEW_WEB_TYPE,
        field=NEW_CHECK_FIELD)
    subs.filter(type=UNMUTE_TYPE).update(
        old_value=NEW_MUTED,
        new_value=NEW_UNMUTED,
        type=NEW_WEB_TYPE,
        field=NEW_CHECK_FIELD)


def update_subs(apps, schema_editor):
    _cleanup_checks(apps)
    _cleanup_accept_suggestion_subs(apps)


class Migration(migrations.Migration):

    replaces = [
        (b'pootle_statistics', '0011_cleanup_submissions'),
        (b'pootle_statistics', '0012_remove_create_subs'),
        (b'pootle_statistics', '0013_remove_revert_flag'),
        (b'pootle_statistics', '0014_truncate_source_subs'),
        (b'pootle_statistics', '0015_remove_system_scorelogs'),
        (b'pootle_statistics', '0016_drop_add_suggestion_subs'),
        (b'pootle_statistics', '0017_drop_reject_suggestion_subs'),
        (b'pootle_statistics', '0018_remove_submission_store'),
        (b'pootle_statistics', '0019_convert_accept_sugg_subs'),
        (b'pootle_statistics', '0020_convert_checks_subs'),
        (b'pootle_statistics', '0021_remove_paid_rates'),
        (b'pootle_statistics', '0022_set_suggestion_submitters'),
        (b'pootle_statistics', '0023_remove_scorelog')]

    dependencies = [
        ('pootle_store', '0045_remove_suggestion_tmp_state'),
        ('pootle_statistics', '0010_submission_on_delete_user')]

    operations = [
        migrations.DeleteModel(
            name='ScoreLog',
        ),
        migrations.RunPython(update_subs),
        migrations.RunPython(cleanup_subs),
        migrations.RemoveField(
            model_name='submission',
            name='store',
        )]
