# -*- coding: utf-8 -*-
from .base import ApiJob, Http400
from common.models import Job, JobTrail, JobImbalance, Component
from django.core.exceptions import ObjectDoesNotExist
from django.db import connection
from django.http import Http404
import logging
from collections import OrderedDict


class JobSummary(ApiJob):
    """
    job info
    """

    def get(self, request, job):
        """
        :param request: http request
        :param job: job object passed from request
        """
        try:
            job = Job.objects.get(n=job.id)

            fields = request.GET.get('fields', '''n,fd,td,person,name,dsc,flag,project,
                            jira_task,jira_task_name,jira_task_status,status,tank,tank,status,
                            command_line,ammo_path,loop_cnt,quit_status,imbalance_rps,
                            last_second_rps,component,component_name,ver,duration,finalized''')
            fields = [f.strip() for f in fields.split(',') if f]
            rules = {
                'n': lambda job: job.n,
                'fd': lambda job: str(job.data_started),
                'td': lambda job: str(job.data_stopped),
                'person': lambda job: job.person,
                'name': lambda job: job.name,
                'dsc': lambda job: job.dsc,
                'flag': lambda job: job.flag,
                'project': lambda job: job.task.split('-')[0] if job.task else '',
                'jira_task': lambda job: job.task,
                'jira_task_name': lambda job: job.task,
                'jira_task_status': lambda job: job.task,
                'tank': lambda job: job.tank.host,
                'target': lambda job: job.srv.host,
                'status': lambda job: self.get_status(job),
                'command_line': lambda job: job.command_line,
                'ammo_path': lambda job: job.ammo_path,
                'loop_cnt': lambda job: round(job.loop_cnt, 2),
                'quit_status': lambda job: job.quit_status,
                'imbalance_rps': lambda job: self.get_imbalance(job),
                'last_second_rps': lambda job: self.get_duration(job)[1],
                'component': lambda job: job.component,
                'component_name': lambda job: self.get_component_name(job),
                'ver': lambda job: job.ver if job.ver else '',
                'duration': lambda job: self.get_duration(job)[0],
                'finalized': lambda job: job.finalized,
            }

            for field in fields:
                if field not in list(rules.keys()):
                    raise Http400('Field {} not found'.format(field))
            res = [OrderedDict(
                [(col, rules[col](job)) for col in fields]
            )]
            return res
        except ObjectDoesNotExist:
            raise Http404('Job not found')
        except:
            logging.exception("")

    @staticmethod
    def get_status(job):
        status = 'offline' if job.td else 'online'
        if status != 'online':
            # try:
            #     JobImbalance.objects.filter(up=job).order_by('rob_isimbalance', '-hum_isimbalance', '-n')[0:1].get()
            # except ObjectDoesNotExist:
            #     status = 'post-processing'
            # try:
            #     JobTrail.objects.get(up=job.id)
            # except ObjectDoesNotExist:
            #     status = 'post-processing'
            if not job.finalized:
                status = 'post-processing'
            if job.status == 'queued':
                status = 'queued'
        return status

    @staticmethod
    def get_component_name(job):
        try:
            regr_comp = Component.objects.get(n=job.component)
            regr_comp_name = regr_comp.name
        except ObjectDoesNotExist:
            regr_comp_name = ''
        return regr_comp_name

    @staticmethod
    def get_imbalance(job):
        try:
            imb = JobImbalance.objects.filter(up=job).order_by('rob_isimbalance', '-hum_isimbalance')[0:1].get()
            if imb.hum_imbalance and imb.hum_isimbalance:
                imb = imb.hum_imbalance
            elif not imb.hum_processed and imb.rob_isimbalance:
                imb = imb.rob_imbalance
            else:
                imb = 0
        except ObjectDoesNotExist:
            imb = 0
        return imb

    @staticmethod
    def get_duration(job):
        # TODO: use clickhouse
        # танк больше не шлёт нормально схемы нагрузки, их надо распарсивать как хелперы из конфигинфо.
        if job.td:
            cursor = connection.cursor()
            cursor.execute(
                "SELECT extract(epoch from td) - extract(epoch from fd) from job where n=%(job)s", {'job': job.n}
            )
            row = cursor.fetchone()
            duration = row[0]
            last_second_rps = 0
            cursor.execute('''
                select load_from+(load_to-load_from)/(sec_to-sec_from)*(%(duration)s-sec_from+1)
                from loadscheme
                where up=%(job)s
                and sec_from<=%(duration)s
                and sec_to>%(duration)s''', {'job': job.n, 'duration': duration}
                           )
            row = cursor.fetchone()
            if row is not None and row[0] is not None:
                last_second_rps = int(row[0])
            else:
                cursor.execute(
                    "select load_to from loadscheme where sec_to =\
                            (select max(sec_to) from loadscheme where up=%(job)s)\
                            and up=%(job)s", {'job': job.n})
                row = cursor.fetchone()
                if row is not None and row[0] is not None:
                    last_second_rps = int(row[0])
        else:
            duration = 0
            last_second_rps = 0

        return duration, last_second_rps

    @staticmethod
    def get_loop_cnt(job):
        if job.loop_cnt is None:
            job.loop_cnt = 0
