# -*- coding: utf-8 -*-
"""
Created on Feb 24, 2014

@author: noob
"""
import logging
from collections import OrderedDict
from json import dumps

from django.http import HttpResponse

from common.models import Server
from common.util.clients import ClickhouseClient
from common.util.decorators import memoized_property
from ..util import get_job_objects


def get_plots_to_show(request):
    """

    :param request: HTTP Request
    """
    jobs = request.GET.get('jobs', '').split(',')
    job_objects = get_job_objects(jobs)

    plot_group = request.GET.get('plot_group', '')
    tab = request.GET.get('tab', '')
    case = request.GET.get('case', '')
    target = request.GET.get('target', '')
    metric_group = request.GET.get('metric_group', '')


    if tab == 'meta_info':
        plot_group = 'meta_info'
    elif tab == 'monitoring':
        plot_group = metric_group

    plot_groups_map = {
        'meta_info': {'meta_info': ['meta_info_table']},
        'test_data': OrderedDict((
            ('additional', [
                'quantiles_vs_times',
                'times_dist_percent_plot',
                'times_dist_count_plot',
            ]),
            ('main', [
                'quantiles_timeline_plot',
                'times_dist_timeline_plot',
                'http_codes_timeline_plot',
                'net_codes_timeline_plot',
            ]),
            ('extended', [
                'avgtimes_timeline_plot',
                'instanses_timeline_plot',
                'sent_received_plot',
            ]),
            ('tables', [
                'quantiles_cumulative_table',
                'http_codes_table',
                'net_codes_table',
                'trail_times_table',
            ]),
        )),
        'monitoring': {
            'Net':
                [
                    'monitoring_net_plot',
                ],
            'CPU':
                [
                    'monitoring_cpu_plot',
                ],
            'Disk':
                [
                    'monitoring_disk_plot',
                ],
            'Memory':
                [
                    'monitoring_memory_plot',
                ],
            'System':
                [
                    'monitoring_system_plot',
                ],
            'aggregates':
                [
                    'monitoring_aggregates_table',
                ],
        },
    }

    if not case and all(bool(job_obj.cases) for job_obj in job_objects):
        if is_multitag(job_objects):
            plot_groups_map['test_data']['tables'].insert(0, 'multitag_dist_table')
            plot_groups_map['test_data']['tables'].insert(0, 'multitag_http_table')
            plot_groups_map['test_data']['tables'].insert(0, 'multitag_net_table')
            plot_groups_map['test_data']['tables'].insert(0, 'multitag_times_table')
            plot_groups_map['test_data']['tables'].insert(0, 'multitag_cumulative_quantiles_table')
        else:
            plot_groups_map['test_data']['tables'].insert(0, 'cases_dist_table')
            plot_groups_map['test_data']['tables'].insert(0, 'cases_http_table')
            plot_groups_map['test_data']['tables'].insert(0, 'cases_net_table')
            plot_groups_map['test_data']['tables'].insert(0, 'cases_cumulative_quantiles_table')
    if tab == 'monitoring':
        custom_metrics_mapper = CustomMetricsPlotsMapper(job_objects, target)
        plot_groups_map['monitoring']['custom'] = custom_metrics_mapper.custom_metric_groups

    plot_list = plot_groups_map[tab][plot_group]

    return HttpResponse(dumps({
        "plots_to_show": plot_list,
    }
    ), content_type='application/json')


def is_multitag(job_objects):
    return all(job_obj.multitag for job_obj in job_objects)


class CustomMetricsPlotsMapper(object):
    def __init__(self, job_objects, target):
        """

        :param job_objects: Job OBJECTS list
        :param target: string Server.n
        """

        self.job_objects = job_objects
        self.target = target

    @memoized_property
    def custom_metrics(self):
        """
        returns dict {target_number:{metric_codes: metric_ids}}
        """
        custom_metrics = []
        ch_client = ClickhouseClient()
        for job_obj in self.job_objects:
            try:
                query_params = job_obj.basic_query_params.copy()
                sql = '''select distinct toString(metric_name)
                        from loaddb.monitoring_verbose_data_buffer
                        where job_id = {job}
                        and job_date = toDate({job_date})
                        and target_host = '{target}'
                        '''
                query_params['target'] = Server.objects.get(n=self.target).host
                metric_ids = ch_client.select(sql, query_params=query_params)
                custom_metrics.extend(metric[0] for metric in metric_ids if metric[0].split(':')[0] == 'custom')
            except:
                logging.exception('Could not get monitoring custom_metrics for job {} due to:'.format(job_obj.n))
        return set(custom_metrics)

    @memoized_property
    def custom_metric_groups(self):
        """
        returns dict {machine.n:[grouped and single metric codes]}
        """
        custom_metrics = [
            custom_metric.split(':')[1].split('_')[0]
            for custom_metric in self.custom_metrics
        ]
        # if not any(custom_metric.split(':')[1].startswith(prefix) for prefix in ('cpu-cpu', 'diskio-', 'net-'))
        single_custom_metrics = [
            'monitoring_customs:{metric}_plot'.format(metric=metric.split(':')[1])
            for metric in self.custom_metrics
            if custom_metrics.count(metric.split(':')[1].split('_')[0]) == 1
        ]
        grouped_custom_metrics = set([
            'monitoring_customg:{metric_group}_plot'.format(metric_group=metric.split(':')[1].split('_')[0])
            for metric in self.custom_metrics
            if custom_metrics.count(metric.split(':')[1].split('_')[0]) > 1
        ])
        custom_metric_groups = list(grouped_custom_metrics) + single_custom_metrics
        return sorted(set(custom_metric_groups))
