"""
Created on Feb 28, 2014

@author: noob
"""

from .plots.dist_plots import QuantilesVsTimes, TimesDistCountPlot, TimesDistPercentPlot
from .plots.monitoring_plots import MonitoringSystemComparePlot, MonitoringCPUComparePlot, MonitoringDiskComparePlot, \
    MonitoringMemoryComparePlot, MonitoringNetComparePlot, MonitoringCustomComparePlot
from .plots.tables import MetaInfoCompareTable, HttpCodesCompareTable, NetCodesCompareTable, TimesDistCompareTable, \
    QuantilesCumulativeCompareTable, CasesDistCompareTable, AggregatesCompareTable, \
    CasesCumulativeQuantilesCompareTable, CasesHttpCodesCompareTable, CasesNetCodesCompareTable, \
    MultitagCumulativeQuantilesCompareTable, MultitagDistCompareTable, MultitagHttpCodesCompareTable, \
    MultitagNetCodesCompareTable, MonitoringAggregatesTable, MultitagTimesCompareTable
from .plots.timeline_plots import QuantilesTimelineComparePlot, HTTPCodesTimelineComparePlot, \
    NetCodesTimelineComparePlot, \
    AvgTimesTimelinePlot, InstancesTimelinePlot, SentReceivedPlot, TimesDistTimelineComparePlot
from common.util.decorators import cached
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
from hashlib import md5
from json import dumps
from urllib.parse import unquote
import logging

plot_types_mapping = {
    'meta_info_table': MetaInfoCompareTable,
    'http_codes_table': HttpCodesCompareTable,
    'net_codes_table': NetCodesCompareTable,
    'trail_times_table': TimesDistCompareTable,
    'quantiles_cumulative_table': QuantilesCumulativeCompareTable,
    'trail_aggregates_table': AggregatesCompareTable,

    'cases_dist_table': CasesDistCompareTable,
    'cases_http_table': CasesHttpCodesCompareTable,
    'cases_net_table': CasesNetCodesCompareTable,
    'cases_cumulative_quantiles_table': CasesCumulativeQuantilesCompareTable,

    'multitag_dist_table': MultitagDistCompareTable,
    'multitag_http_table': MultitagHttpCodesCompareTable,
    'multitag_net_table': MultitagNetCodesCompareTable,
    'multitag_times_table': MultitagTimesCompareTable,
    'multitag_cumulative_quantiles_table': MultitagCumulativeQuantilesCompareTable,

    'times_dist_count_plot': TimesDistCountPlot,
    'times_dist_percent_plot': TimesDistPercentPlot,
    'quantiles_vs_times': QuantilesVsTimes,

    'quantiles_timeline_plot': QuantilesTimelineComparePlot,
    'http_codes_timeline_plot': HTTPCodesTimelineComparePlot,
    'net_codes_timeline_plot': NetCodesTimelineComparePlot,
    'times_dist_timeline_plot': TimesDistTimelineComparePlot,

    'avgtimes_timeline_plot': AvgTimesTimelinePlot,
    'instanses_timeline_plot': InstancesTimelinePlot,
    'sent_received_plot': SentReceivedPlot,

    'monitoring_cpu_plot': MonitoringCPUComparePlot,
    'monitoring_disk_plot': MonitoringDiskComparePlot,
    'monitoring_memory_plot': MonitoringMemoryComparePlot,
    'monitoring_net_plot': MonitoringNetComparePlot,
    'monitoring_system_plot': MonitoringSystemComparePlot,
    'monitoring_custom_plot': MonitoringCustomComparePlot,

    'monitoring_aggregates_table': MonitoringAggregatesTable,
}


def get_plot_data(request):
    """
    deals with memcache
    retrieves request parameters
    defines monitoring custom metrics plots and passes custom metric as a plot param (None by default)
    calls plot_data function;
    :param request: HTTP Request
    """
    plot_type = request.GET.get('plot_type', '')
    jobs = request.GET.get('jobs', '')
    helper = request.GET.get('helper', '')
    case = unquote(request.GET.get('case', ''))
    target = request.GET.get('target', '')
    mainjob = request.GET.get('mainjob', '')
    selector = request.GET.get('selector', '')
    tab = request.GET.get('tab', '')

    if tab == 'monitoring' and plot_type.split('_')[-1] == 'table':
        memcache_key = 'jobs_{}_compareplot_{}_helper_{}_target_{}_mainjob_{}_selector_{}'.format(
            jobs, plot_type, helper, target, mainjob, selector)
    elif tab == 'monitoring':
        memcache_key = 'jobs_{}_compareplot_{}_helper_{}_target_{}_selector_{}'.format(
            jobs, plot_type, helper, target, selector)
    elif plot_type.split('_')[-1] == 'table':
        memcache_key = 'jobs_{}_compareplot_{}_helper_{}_case_{}_mainjob_{}_selector_{}'.format(
            jobs, plot_type, helper, md5(case.encode('utf-8')).hexdigest(), mainjob, selector)
    else:
        memcache_key = 'jobs_{}_compareplot_{}_helper_{}_case_{}_selector_{}'.format(
            jobs, plot_type, helper, md5(case.encode('utf-8')).hexdigest(), selector)

    @cached(memcache_key)
    def plot_data():
        if tab == 'monitoring':
            if plot_type.split('_')[1].split(':')[0][:-1] == 'custom':
                custom_metric = '_'.join(plot_type.split('@')[0].split('_')[1:-1])
                plot = MonitoringCustomComparePlot(jobs, mainjob=mainjob, helper=helper, case=case, target=target,
                                                   selector=selector, custom_metric=custom_metric)
            else:
                plot = plot_types_mapping[plot_type](jobs, mainjob=mainjob, helper=helper, case=case, target=target,
                                                     selector=selector)
        else:
            plot = plot_types_mapping[plot_type](jobs, mainjob=mainjob, helper=helper, case=case, target=target,
                                                 selector=selector)
        return {'title': plot.title,
                'subtitle': plot.subtitle,
                'table': plot.table,
                'data': plot.get_data(),
                'compress_ratio': plot.compress_ratio,
                'overrides': plot.overrides,
                'x': {'values': 'xaxis',
                      'type': plot.xaxis_type},
                #                 'y':plot.yaxis,
                }

    try:
        return HttpResponse(dumps(plot_data()), content_type='application/json')
    except KeyError:
        logging.exception('No such plot type {}'.format(plot_type))
        return HttpResponseBadRequest()
    except:
        logging.exception('Could not get plot "{}" for job {} due to:'.format(plot_type, jobs))
        return HttpResponseServerError()
