# -*- coding: utf-8 -*-
"""
Created on Apr 12, 2013

@author: noob
"""
from common.models import Job, LoadScheme, Task
from common.util.clients import StartrekClient, st_statuses, st_statuses_img_path
from common.views import get_common
from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import render_to_response
from django.template import RequestContext
from django_yauth.decorators import yalogin_required
import logging
import json


@yalogin_required
def project_page(request, requested_project):
    """

    :param request: HTTP Request
    :param requested_project: string - project_obj value passed in request
    """
    common_data = get_common(request)
    selector = request.GET.get('select', 'open')
    try:
        # TODO: validate requested project. check if it exists in st or if there are jobs with tasks from it;
        assert True
    except AssertionError:
        page_error = 'no_project'
        return render_to_response('error.html', {'common': common_data, 'error': page_error},
                                  RequestContext(request))
    return render_to_response('projectpage.html', {'common': common_data,
                                                   'project': requested_project.upper(),
                                                   'selector': selector,
                                                   }, RequestContext(request))


@yalogin_required
def get_tasks_block(request):
    """
    Ручка, которая рендерит больше тасков для отображения при скролле в bottom.
    :param request:
    :return:
    """
    try:
        selector = request.GET.get('select', 'open')
        project = request.GET.get('project_code')
        page = int(request.GET.get('page', 0))
        limit = int(request.GET.get('limit', 50))

        stop_iteration = False

        tasks = []
        paginator = Paginator(Task.objects.filter(key__startswith='{}-'.format(project)).order_by('-n'), limit)
        while len(tasks) < limit and not stop_iteration:
            page += 1
            try:
                db_tasks = paginator.page(page)
            except EmptyPage:
                stop_iteration = True
                db_tasks = []
            if not stop_iteration:
                st_tasks = StartrekClient().get_tasks([t.key for t in db_tasks])
                if selector == 'open':
                    st_tasks = [t for t in st_tasks if not t.resolution]
            else:
                st_tasks = []

            tasks.extend({
                'key': task.key.upper(),
                'name': task.summary,
                'assignee': task.assignee.id if task.assignee else '',
                'createdAt': task.createdAt.split('.')[0].replace('T', ' '),
                'createdBy': task.createdBy.id if task.createdBy else '',
                'status_img': st_statuses_img_path + st_statuses.get(task.status.key, st_statuses['']),
                'status': task.status.key,
            } for task in st_tasks)

        return HttpResponse(json.dumps({
            "tasks": sorted(tasks, key=lambda t: int(t['key'].split('-')[1]), reverse=True),
            "selector": selector,
            "stop_iteration": stop_iteration,
            "page": page,
        }), content_type="application/json")

        # return render_to_response('tasks_block.html', {
        #     "tasks": sorted(tasks, key=lambda t: int(t['key'].split('-')[1]), reverse=True),
        #     "selector": selector,
        #     "stop_iteration": stop_iteration,
        #     "page": page,
        # }, RequestContext(request))

    except Exception as exc:
        logging.exception('Could not get tasks due to:', exc_info=True)
        return HttpResponseServerError(exc)


@yalogin_required
def get_jobs_popup(request, requested_task):
    """
    :param request: HTTP Request
    :param requested_task: string - task key passed in request
    """
    try:
        jobs = Job.objects.filter(task=requested_task).order_by('-n')[0:10]
        return render_to_response('jobs_popup.html', {
            'task': requested_task,
            'jobs': jobs,
            'not_all_jobs': (Job.objects.filter(task=requested_task).count() > 10),
            'job_start_rps_dict': get_job_start_rps(jobs),
            'job_finish_rps_dict': get_job_finish_rps(jobs),
            'job_quit_status_dict': {job_obj.n: job_obj.quit_status_text for
                                     job_obj in jobs},
        }, RequestContext(request))
    except Exception as exc:
        logging.exception('Could not get jobs for task {} due to:'.format(requested_task))
        return HttpResponseServerError(exc.message)


def get_job_loadschemes(job):
    """
    auxiliary method
    returns list of LoadScheme objects
    :param job: job object
    """
    try:
        loadscheme_list = LoadScheme.objects.filter(up=job)
        return loadscheme_list
    except ObjectDoesNotExist:
        logging.exception('LoadScheme DoesNotExist for job {}'.format(job))
        return None
    except:
        logging.exception('problems while processing loadscheme for job {}:'.format(job))
        return None


def get_job_start_rps(jobs):
    """
    :param jobs: list of job object
    """
    job_start_rps_dict = {}
    for job in jobs:
        try:
            loadscheme_list = get_job_loadschemes(job)
            if loadscheme_list:
                job_start_rps = min([loadscheme.load_from for loadscheme in loadscheme_list])
            else:
                job_start_rps = 0
            job_start_rps_dict[job.n] = int(job_start_rps)
        except:
            logging.exception('problems while processing job imbalance for job {}:'.format(job))
            job_start_rps_dict[job.n] = 0
    return job_start_rps_dict


def get_job_finish_rps(jobs):
    """
    :param jobs: list of job object
    """
    job_finish_rps_dict = {}
    for job in jobs:
        try:
            loadscheme_list = get_job_loadschemes(job)
            if loadscheme_list:
                job_finish_rps = max([loadscheme.load_to for loadscheme in loadscheme_list])
            else:
                job_finish_rps = 0
            job_finish_rps_dict[job.n] = int(job_finish_rps)
        except:
            logging.exception('problems while processing job imbalance for job {}:'.format(job))
            job_finish_rps_dict[job.n] = 0
    return job_finish_rps_dict


def job_star_toggle_request_handler(request, requested_job):
    """

    :param request: HTTP Request
    :param job: string - job.n passed in request
    """
    response = job_star_toggle(requested_job)
    return HttpResponse(response)


def job_star_toggle(requested_job):
    """
    auxiliary method
    :param requested_job: string - job.n passed in request
    """
    try:
        job_obj = Job.objects.get(n=requested_job)
        if job_obj.flag:
            job_obj.flag = '0'
        else:
            job_obj.flag = '1'
        job_obj.save()
        return [{'success': 1}]
    except ObjectDoesNotExist:
        logging.error('Job {} DoesNotExist'.format(requested_job))
        return [{'success': 0}]
    except:
        logging.exception('Could not toggle star for job {} due to:'.format(requested_job))
        return [{'success': 0}]
