# -*- coding: utf-8 -*-
"""
Created on Jul 26, 2013

@author: noob
"""

# from common.util.decorators import approve_required
# from django.contrib.auth.decorators import login_required
from .plots.dist_plots import TimesDistPlot, QuantilesVsTimes, QuantilesVsRps, QuantilesVsInstanses, \
    AvgTimesVsRps, AvgTimesVsInstanses
from .plots.monitoring_plots import MonitoringCPUPlot, MonitoringCustomPlot, MonitoringDiskPlot, MonitoringMemoryPlot, \
    MonitoringNetPlot, MonitoringSystemPlot, TelegrafCPUPlot, TelegrafDiskPlot, TelegrafNetPlot
from .plots.tables import CasesDistTable, CasesNetCodesTable, CasesHttpCodesTable, CasesCumulativeQuantilesTable, \
    QuantilesCumulativeTable, TimesDistTable, MonitoringAggregatesTable, HttpDistTable, NetDistTable, \
    AggregatesTable, MultitagCumulativeQuantilesTable, MultitagHttpCodesTable, MultitagNetCodesTable, \
    MultitagDistTable
from .plots.timeline_plots import QuantilesTimelinePlot, HTTPCodesTimelinePlot, NetCodesTimelinePlot, \
    AvgTimesTimelinePlot, InstancesTimelinePlot, \
    SentReceivedPlot, CasesTimelinePlot, CasesAvgTimelinePlot, TimesDistTimelinePlot
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
from django.utils.datastructures import MultiValueDictKeyError
from json import dumps
import logging

plot_types_mapping = {
    'quantiles_timeline_plot': QuantilesTimelinePlot,
    'http_timeline_plot': HTTPCodesTimelinePlot,
    'net_timeline_plot': NetCodesTimelinePlot,
    'times_dist_table': TimesDistTable,
    'cases_avg_timeline_plot': CasesAvgTimelinePlot,
    'timesdist_timeline_plot': TimesDistTimelinePlot,
    'cases_timeline_plot': CasesTimelinePlot,
    'avgtimes_timeline_plot': AvgTimesTimelinePlot,
    'sent_received_plot': SentReceivedPlot,
    'instanses_timeline_plot': InstancesTimelinePlot,

    'times_dist_plot': TimesDistPlot,
    'quantiles_vs_times': QuantilesVsTimes,
    'quantiles_vs_rps': QuantilesVsRps,
    'quantiles_vs_instanses': QuantilesVsInstanses,

    'cases_dist_table': CasesDistTable,
    'cases_netcodes_table': CasesNetCodesTable,
    'cases_httpcodes_table': CasesHttpCodesTable,
    'cases_cumulative_quantiles_table': CasesCumulativeQuantilesTable,
    'multitag_dist_table': MultitagDistTable,
    'multitag_cumulative_quantiles_table': MultitagCumulativeQuantilesTable,
    'multitag_httpcodes_table': MultitagHttpCodesTable,
    'multitag_netcodes_table': MultitagNetCodesTable,
    'http_dist_table': HttpDistTable,
    'net_dist_table': NetDistTable,
    'quantiles_cumulative_table': QuantilesCumulativeTable,
    'aggregates_table': AggregatesTable,
    'avgtimes_vs_rps': AvgTimesVsRps,
    'avgtimes_vs_instanses': AvgTimesVsInstanses,

    'monitoring_net_plot': MonitoringNetPlot,
    'monitoring_disk_plot': MonitoringDiskPlot,
    'monitoring_memory_plot': MonitoringMemoryPlot,
    'monitoring_cpu_plot': MonitoringCPUPlot,
    'monitoring_system_plot': MonitoringSystemPlot,

    'monitoring_aggregates_table': MonitoringAggregatesTable,
}


# @login_required # let offlinepage be viewed by unauthorized users
# @approve_required
def get_plot_data(request, job):
    """
    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
    :param job: Job NUMBER
    """
    try:
        plot_type = request.GET['plot_type']
        slider_start = request.GET['slider_start']  # '%Y-%m-%d %H:%M:%S'
        slider_end = request.GET['slider_end']  # '%Y-%m-%d %H:%M:%S'
        compress_ratio = request.GET['compress_ratio']
    except (MultiValueDictKeyError, TypeError):
        logging.exception('BadRequest')
        return HttpResponseBadRequest('')
    case = request.GET.get('tags', '')
    machine = request.GET.get('machines', '')
    try:
        if plot_type.startswith('monitoring'):
            if plot_type.split('_')[1].split(':')[0][0:-1].lower() == 'custom':
                custom_metric = '_'.join(plot_type.split('@')[0].split('_')[1:-1])
                plot = MonitoringCustomPlot(job, slider_start, slider_end, compress_ratio, machine, custom_metric)
            else:
                plot = plot_types_mapping[plot_type.split('@')[0]](job, slider_start, slider_end, compress_ratio,
                                                                   machine)
        elif plot_type.startswith('telegraf'):
            if plot_type.split(':')[1].lower().startswith('cpu-cpu'):
                custom_metric = '_'.join(plot_type.split('@')[0].split('_')[1:-1])
                plot = TelegrafCPUPlot(job, slider_start, slider_end, compress_ratio, machine, custom_metric)
            elif plot_type.split(':')[1].lower().startswith('diskio-'):
                custom_metric = '_'.join(plot_type.split('@')[0].split('_')[1:-1])
                plot = TelegrafDiskPlot(job, slider_start, slider_end, compress_ratio, machine, custom_metric)
            elif plot_type.split(':')[1].lower().startswith('net-'):
                custom_metric = '_'.join(plot_type.split('@')[0].split('_')[1:-1])
                plot = TelegrafNetPlot(job, slider_start, slider_end, compress_ratio, machine, custom_metric)
        else:
            plot = plot_types_mapping[plot_type](job, slider_start, slider_end, compress_ratio, case)
        data = plot_data(plot)
        return HttpResponse(dumps(data), content_type='application/json')
    except KeyError:
        logging.exception('No such plot type %s', plot_type)
        response = {
            'success': 0,
            'error': 'No such plot type %s' % plot_type}
        return HttpResponseBadRequest(dumps(response), content_type='application/json')
    except:
        logging.exception('Could not get plot "%s" for job %s due to:', plot_type, job)
        return HttpResponseServerError('')


def plot_data(plot):
    """
    forms a dict, operating with plot object
    saves data into cache;
    :param plot: Plot object
    """
    try:
        data = {
            'title': plot.title,
            'subtitle': plot.subtitle,
            'table': plot.table,
            'data': plot.get_data(),
            'overrides': plot.overrides,
            'x': {'values': 'point',
                  'type': plot.xaxis_type},
            'y': plot.yaxis
        }
        return data
    except:
        logging.exception('Could not get plot %s data for job %s due to:', plot.__class__.__name__, plot.job)
        return None
