# coding=utf-8
"""更新日记本评论到日记贴。"""

import copy
import math
import time
from multiprocessing import Pool, Manager

from django.core.management.base import BaseCommand
from django.db.models import Q, Max
from django import db
from django.conf import settings

from talos.models.diary import Diary
from talos.models.topic import TopicReply


filter_diary_query = Q(is_online=True)
filter_topicreply_query = Q(is_online=True) & Q(problem__isnull=True)


def update_diary_reply2topic(queue, limit):

    start_id = queue.get()
    diaries = Diary.objects.using(settings.SLAVE_DB_NAME).filter(Q(pk__gt=start_id) & filter_diary_query)[: limit]
    max_id = diaries.aggregate(max_id=Max('id'))
    queue.put(max_id["max_id"])
    if not diaries:
        return

    for diary in diaries:
        topics = diary.topics.order_by("created_time")
        if not topics:
            continue

        replies_update = []
        topics_update = []
        replies = TopicReply.objects.filter(filter_topicreply_query & Q(diary_id=diary.id))
        for reply in replies:
            length = len(topics)
            pre = None

            for idx, topic in enumerate(list(topics)):

                if not pre:
                    pre = topic
                nex = topic

                if pre != nex:
                    if reply.reply_date < pre.created_time or reply.reply_date >= nex.created_time:
                        pre = nex
                        if idx + 1 != length:  # 不是最后一次（可能最后一次，时间归到最后一个日记帖）
                            continue
                else:
                    if idx + 1 != length:  # 可能只有一个topic
                        pre = nex
                        continue

                reply.problem_id = pre.id
                reply.diary_id = None
                replies_update.append(reply)
                pre.reply_num += 1
                topics_update.append(pre)
                break

        [reply.save(update_fields=['problem_id', 'diary_id']) for reply in replies_update]
        [topic.save(update_fields=['reply_num']) for topic in topics_update]

    print(start_id)


class Command(BaseCommand):

    def handle(self, *args, **options):

        print('------ starting -----')
        start_time = time.time()
        print("start at: ", start_time)

        queue = Manager().Queue(maxsize=1)
        queue.put(0)  # 触发程序开始

        args_list = []
        per_num = 200
        count = Diary.objects.filter(filter_diary_query).count()
        cnt = int(math.ceil(count/per_num))
        for _ in range(cnt):
            args_list.append((queue, per_num))

        db.connections.close_all()
        pool = Pool(processes=4)
        pool.starmap(update_diary_reply2topic, args_list)
        pool.close()
        pool.join()

        end_time = time.time()
        print("end at: ", end_time)
        print('total use {} s.'.format(end_time - start_time))
        print('Done!')
