from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.core.cache import cache
from django.utils.html import escape

from .cluster import get_cluster_data as cluster
from .yasm_digits import check_hosts

import json
import traceback


def get_index_rates(request):
    ctype = request.GET.get('ctype', 'stable')
    dm_addr = request.GET.get('dm', '')
    try:
        services = cluster.get_services(ctype, dm_addr=dm_addr)[0]
    except Exception as e:
        return HttpResponse(json.dumps({'success': False, 'error': 'while getting services: %s' % e}))
    try:
        cache_key = 'yasm-index-rates-' + ctype
        serv_rates = cache.get(cache_key)
        ipr_tag = 'indexerproxy_self'
        if not serv_rates:
            sig_data = dict([(serv, {
                'i200': ipr_tag + ':saas_unistat-index-%s-%s-200_dmmm' % (ctype, serv)
            }) for serv in services])
            sig_list = []
            for serv, cols in sig_data.items():
                sig_list.extend(cols.values())
            DAY_SEC = 86400
            tst = check_hosts(['ASEARCH'], sig_list, DAY_SEC, 3)
            result = {}
            for serv, sd in sig_data.items():
                result[serv] = -1
                for portion in tst['ASEARCH']:
                    for ts, signals in portion:
                        result[serv] = max(result[serv], signals.get(sd['i200'], 0) or 0)
            serv_rates = result
            cache.set(cache_key, serv_rates, 600)
    except Exception as e:
        return HttpResponse(json.dumps({'success': False, 'error': 'while getting golovan signals: %s' % e}))

    rates = serv_rates
    return HttpResponse(json.dumps({'result': rates, 'success': True, 'request': escape(request.GET), 'services_num': len(services)}))


def signals_digits(request):
    table = request.GET.get('table')
    table = table or 'common'
    if table not in ['common', ]:
        return HttpResponse('not found table %s' % table)

    service = request.GET.get('service', '')
    ctype = request.GET.get('ctype', 'stable')
    try:
        services = service.split(',') if service else cluster.get_services(ctype)[0]
    except Exception as e:
        return HttpResponse('%s' % e)
    #  return HttpResponse(json.dumps(services))
    try:
        cache_key = 'common-%s-%s' % (ctype, '.'.join(services[:10]))
        serv_sorted = cache.get(cache_key)
        tst = 'cached'
        errors = {}
        if not serv_sorted:
            sig_data = dict([(serv, {
                'search': 'searchproxy_self:saas_unistat-search-%s-%s-200_dmmm' % (ctype, serv),
                'search-nonzero': 'searchproxy_self:hcount~saas_unistat-times-%s-nonzero-%s_dhhh~0~inf' % (ctype, serv),
                'cpu-load': 'rtyserver_self:aver~rty_infoserver-%s-%s-cpu_load_user_tvvv' % (serv, ctype),
                'memory': 'rtyserver_self:aver~rty_infoserver-%s-%s-mem_size_real_tvvv' % (serv, ctype),
                'index': 'indexerproxy_self:saas_unistat-index-%s-%s-200_dmmm' % (ctype, serv)
            })
                for serv in services])
            sig_list = []
            for serv, cols in sig_data.items():
                sig_list.extend(cols.values())
            DAY_SEC = 86400
            FIVEMIN_SEC = 300
            WEEK_5MIN = 3 * 24 * 3600 / FIVEMIN_SEC
            tst = check_hosts(['ASEARCH'], sig_list, DAY_SEC, 4)
            result_search = {}
            for serv, sd in sig_data.items():
                result_search[serv] = {}
                # return                 HttpResponse('%s' % tst['ASEARCH'])
                for portion in tst['ASEARCH']:
                    for ts, signals in portion:
                        result_search[serv]['search'] = result_search.get(serv, {}).get('search', 0) + (signals.get(sd['search'], 0) or 0)
                        result_search[serv]['search-nonzero'] = result_search.get(serv, {}).get('search-nonzero', 0) + (signals.get(sd['search-nonzero'], 0) or 0)
                        result_search[serv]['index'] = result_search.get(serv, {}).get('index', 0) + (signals.get(sd['index'], 0) or 0)
                        try:
                            result_search[serv]['cpu-load'] = result_search.get(serv, {}).get('cpu-load', 0) + (signals.get(sd['cpu-load'], 0) or 0)
                            result_search[serv]['memory'] = result_search.get(serv, {}).get('memory', 0) + (signals.get(sd['memory'], 0) or 0)
                        except:
                            pass
            maxmins = check_hosts(['ASEARCH'],
                                  ['searchproxy_self:saas_unistat-search-%s-%s-200_dmmm' % (ctype, serv) for serv in services] +
                                  ['indexerproxy_self:saas_unistat-index-%s-%s-200_dmmm' % (ctype, serv) for serv in services],
                                  FIVEMIN_SEC, WEEK_5MIN)
            # return                 HttpResponse('%s' % maxmins['ASEARCH'])
            for serv, sigs in sig_data.items():
                try:
                    for portion in maxmins['ASEARCH']:
                        sig_values = [v.get(sigs['search'], -1) for ts, v in portion if sigs['search'] in v]
                        if sig_values:
                            result_search[serv]['rpsmax'] = max(sig_values)
                            result_search[serv]['rpsmin'] = min([c for c in sig_values if c > 0] or [0, ])
                        sig_values = [v.get(sigs['index'], -1) for ts, v in portion if sigs['index'] in v]
                        if sig_values:
                            result_search[serv]['irpsmax'] = max(sig_values)
                            result_search[serv]['irpsmin'] = min([c for c in sig_values if c > 0] or [0, ])
                    if 'rpsmax' not in result_search[serv]:
                        result_search[serv]['rpsmax'] = -1
                        result_search[serv]['rpsmin'] = -1
                    if 'irpsmax' not in result_search[serv]:
                        result_search[serv]['irpsmax'] = -1
                        result_search[serv]['irpsmin'] = -1
                except Exception as e:
                    result_search[serv] = result_search.get(serv, {})
                    errors[serv] = 'error on maxmin %s, service %s, values %s' % (e, serv, sigs)
                    # return HttpResponse(errors[serv])
            try:
                sizes = cluster.get_services_sizes(ctype, '')
                if 'result' in sizes:
                    for serv, ss in sizes['result'].items():
                        result_search[serv]['docs-replica'] = ss['docs_in_replica']
                        result_search[serv]['docs-size'] = round(float(ss['result.files_size.__SUM'])/1000000000, 2) \
                            + (0.01 if 1000000000 > ss['result.files_size.__SUM'] > 0 else 0)
                        rids = ss.get('replic_id', {})
                        result_search[serv]['replicas'] = '%s x %s = %s' % (len(rids),
                                                                            rids.values()[0] if rids.values() else 0,
                                                                            sum(rids.values()))
            except Exception:
                pass
            serv_sorted = sorted([{
                'service': serv,
                'search_rps':  round(float(value['search'])/(DAY_SEC*7) + 0.01 if value['search'] > 0 else 0, 2),
                'nonzero_rps': round(float(100 * value.get('search-nonzero', -1)) / (value.get('search', -1)), 2)
                                    if value.get('search-nonzero', -1) > 0 and value.get('search', -1) > 0 else 0,
                'index_rps': round(float(value.get('index', -1))/(DAY_SEC*7) + 0.01 if value.get('index', 0) > 0 else 0, 2),
                'cpu': round(float(value.get('cpu-load', -1))/(0.2*DAY_SEC*7) + 0.01 if value.get('cpu-load', 0) > 0 else 0, 2),
                'memory': round(float(value.get('memory', -1))/(0.2*DAY_SEC*7*1000) + 0.01 if value.get('memory', 0) > 0 else 0, 2),
                'max_rps': round(float(value.get('rpsmax', -1))/FIVEMIN_SEC + 0.01 if value.get('rpsmax', 0) > 0 else 0, 2),
                'min_rps': round(float(value.get('rpsmin', -1))/FIVEMIN_SEC + 0.01 if value.get('rpsmin', 0) > 0 else 0, 2),
                'max_rps_ind': round(float(value.get('irpsmax', -1))/FIVEMIN_SEC + 0.01 if value.get('irpsmax', 0) > 0 else 0, 2),
                'min_rps_ind': round(float(value.get('irpsmin', -1))/FIVEMIN_SEC + 0.01 if value.get('irpsmin', 0) > 0 else 0, 2),
                'replica_docs': value.get('docs-replica', ''),
                'doc_size': value.get('docs-size', ''),
                'replicas': value.get('replicas', '')
                }
                for serv, value in result_search.items()],
                key=lambda x: x['search_rps'], reverse=True)
            cache.set(cache_key, serv_sorted, 120)
    except Exception as e:
        return HttpResponse('error: %s\ntrace:\n%s' % (e, traceback.format_exc()))
    if request.GET.get('format') == 'json':
        return HttpResponse('%s' % serv_sorted)
    elif request.GET.get('format') == 'plain':
        return HttpResponse('ctype = ' + escape(ctype) +
                            '<br><table><tr><td>service</td><td>search rps</td><td>nonzero rps, %</td>'
                            + '<td>max rps</td><td>min rps</td><td>cpu</td><td>memory</td>'
                            + '<td>docs in rep</td><td>docs size</td><td>index rps</td></tr>' +
                            ''.join(['<tr><td>' + r['service'] + '</td><td>'
                                     + str(r['search_rps']) + '</td><td>'
                                     + str(r['nonzero_rps']) + '</td><td>'
                                     + str(r['max_rps']) + '</td><td>'
                                     + str(r['min_rps']) + '</td><td>'
                                     + str(r['cpu']) + '</td><td>'
                                     + str(r['memory']) + '</td><td>'
                                     + str(r['replica_docs']) + '</td><td>'
                                     + str(r['doc_size']) + '</td><td>'
                                     + str(r['index_rps']) + '</td></tr>'
                                     for r in serv_sorted]) + '</table>')
    else:
        return render_to_response('services_table.html',
                                  {
                                      'ctype': ctype,
                                      'data': serv_sorted,
                                      'errors': errors,
                                      'debug_info': tst
                                  })
