from django.http import HttpResponse
from django.http import HttpResponseBadRequest
from django.shortcuts import render_to_response
from django.utils.html import escape

from .cluster import get_cluster_data as cluster
from .people import is_saas_developer
from . import mails

import json
import urllib
try:
    import urllib2
except:
    import urllib.request as urllib2


def service_cluster_table(request):
    service = request.GET.get('service')
    ctype = request.GET.get('ctype')
    if not service or not ctype:
        return HttpResponseBadRequest('service or ctype not set')
    metrics = request.GET.get('metrics') or ''
    res = cluster.get_service_cluster_info(service, ctype, metrics)
    return HttpResponse(json.dumps(res))


def total_cluster_info(request):
    service = request.GET.get('service') or ''
    ctype = request.GET.get('ctype')
    if not ctype:
        return HttpResponseBadRequest('ctype not set')
    return render_to_response('cluster_total_info.html', {'ctype': ctype, 'service': service})


def total_cluster_table(request):
    service = request.GET.get('service') or ''
    ctype = request.GET.get('ctype')
    filters = request.GET.get('filters', 'neighbors')
    if not ctype:
        return HttpResponseBadRequest('ctype not set')
    res = cluster.get_total_cluster_info(service, ctype, filters)
    return HttpResponse(json.dumps(res))


def cluster_queues(request):
    ctype = request.GET.get('ctype')
    res = cluster.get_iproxy_queues(ctype)
    return HttpResponse(json.dumps(res))


def cluster_map_proxies(request):
    ctype = request.GET.get('ctype')
    if not ctype:
        return HttpResponseBadRequest(json.dumps({'success': False,
                                                  'error': 'ctype not specified'}))
    res_sproxy = cluster.cluster_proxies_state(ctype, 'searchproxy')
    res_iproxy = cluster.cluster_proxies_state(ctype, 'indexerproxy')
    res = {'success': res_sproxy['success'] and res_iproxy['success'],
           'searchproxy': res_sproxy,
           'indexerproxy': res_iproxy}
    return HttpResponse(json.dumps(res))


def cluster_map_repshards(request):
    ctype = request.GET.get('ctype')
    skip_eps = request.GET.get('skip_eps')
    if not ctype:
        return HttpResponseBadRequest(json.dumps({'success': False,
                                                  'error': 'ctype not specified'}))
    res_replicas = cluster.get_repshards_state(ctype, 'replicas', skip_eps)
    res_shards = cluster.get_repshards_state(ctype, 'shards', skip_eps)
    res = {'success': res_replicas['success'] and res_shards['success'],
           'replicas': res_replicas, 'shards': res_shards}
    return HttpResponse(json.dumps(res))


def cluster_map(request):
    ctype = request.GET.get('ctype')
    if not ctype:
        return HttpResponseBadRequest('ctype not specified')
    return render_to_response('cluster_map.html', {'ctype': ctype})


def do_command_on_slot(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))
    slot = request.GET.get('slot')
    command = request.GET.get('command')
    if not slot or not command:
        return HttpResponseBadRequest(json.dumps({'success': False, 'error': 'slot or command not set'}))
    cmd = '&'.join([f + '=' + v for f, v in request.GET.items() if f != 'slot'])
    addr = 'http://' + slot + '?' + cmd
    success = True

    service = request.GET.get('service', '')
    ctype = request.GET.get('ctype', '')
    if command.lower() not in ('enable_search', 'clear_data_status'):
        mails.send_dm_mail('manual-' + command + ' ' + service + '-' + ctype,
                           'slot: ' + slot + '\nlogin: ' + login)
    try:
        resp = urllib2.urlopen(addr, timeout=60).read().decode('utf-8')
    except urllib2.HTTPError as e:
        resp = '%s' % e
    except Exception as e:
        resp = '%s' % e
        success = False
    return HttpResponseBadRequest(json.dumps({'success': success, 'result': resp}))


def do_command_as_proxy(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))
    host = request.GET.get('h')
    if not host.startswith('http'):
        host = 'http://' + host
    addr = host + '?' + urllib.parse.urlencode(dict([(f, v) for f, v in request.GET.items() if f != 'h']), True)
    try:
        resp = urllib2.urlopen(addr).read()
    except urllib2.HTTPError as e:
        resp = ('%s' % e) + '\n' + str(e.read())
    except Exception as e:
        resp = '%s' % e
    return HttpResponse(resp, content_type='application/json')


def tags_info(request):
    service = request.GET.get('service')
    ctype = request.GET.get('ctype')
    res = cluster.get_tags_info(service, ctype)
    return HttpResponse(json.dumps(res))


def modify_tags_info(request):
    param_names = ('service', 'ctype', 'action', 'nanny_services', 'slots', 'exclude', 'use_container_names', 'endpointsets')
    params = {}
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    if params['service'] in ('searchproxy', 'indexerproxy', 'deploy_manager'):
        params['service_type'] = params['service']
    else:
        params['service_type'] = 'rtyserver'
    params['login'] = login

    mails.send_dm_mail('modify_tags_info ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.modify_tags_info(params)
    return HttpResponse(json.dumps(res))


def modify_searchmap(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('action', 'service', 'ctype', 'deploy_proxies', 'deploy', 'slots_vector', 'may_be_dead_procentage')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    if not params['may_be_dead_procentage']:
        params['may_be_dead_procentage'] = '0.01'
    if params['service'] in ('searchproxy', 'indexerproxy', 'deploy_manager'):
        params['service_type'] = params['service']
    else:
        params['service_type'] = 'rtyserver'
    params['login'] = login

    if params['deploy']:
        mails.send_dm_mail('modify_searchmap-deploy ' +
                           params['service'] + '-' + params['ctype'],
                           'cmd=' + json.dumps(params) + '\nlogin=' + login)
    else:
        mails.send_dm_mail('modify_searchmap ' +
                           params['service'] + '-' + params['ctype'],
                           'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.modify_searchmap(params)
    if params['deploy'] and res['success'] and len(res['ans']) > 200:
        res['ans'] = 'Ok, new_searchmap_length=' + str(len(res['ans']))
    return HttpResponse(json.dumps(res))


def add_replica(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('service', 'ctype', 'deploy_proxy',
                   'slots_count', 'replicas_count',
                   'slots_allocator', 'restore',
                   'may_be_dead_procentage')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    if not params['may_be_dead_procentage']:
        params['may_be_dead_procentage'] = '0.01'

    if params['service'] in ('searchproxy', 'indexerproxy', 'deploy_manager'):
        params['service_type'] = params['service']
    else:
        params['service_type'] = 'rtyserver'
    params['login'] = login

    mails.send_dm_mail('add_replica ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.add_replica(params)
    return HttpResponse(json.dumps(res))


def restore_slots(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('service', 'ctype', 'deploy_proxies', 'may_be_dead_procentage')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    params['restore_slots'] = request.GET.get('slots')
    if not params['may_be_dead_procentage']:
        params['may_be_dead_procentage'] = '0.01'
    params['login'] = login

    mails.send_dm_mail('restore_slots ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.cluster_control(params)
    return HttpResponse(json.dumps(res))


def replace_slots(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('service', 'ctype', 'deploy_proxies', 'may_be_dead_procentage',
                   'new_slots_pool', 'absent_replace_slots')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    if not params['may_be_dead_procentage']:
        params['may_be_dead_procentage'] = '0.01'
    params['replace_slots'] = request.GET.get('slots')

    params['login'] = login
    mails.send_dm_mail('replace_slots ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.cluster_control(params)
    return HttpResponse(json.dumps(res))


def release_slots(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('service', 'ctype', 'slots', 'deploy_proxies', 'may_be_dead_procentage')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    params['config_type'] = 'default'
    if params['service'] in ('searchproxy', 'indexerproxy', 'deploy_manager'):
        params['service_type'] = params['service']
    else:
        params['service_type'] = 'rtyserver'

    if not params['may_be_dead_procentage']:
        params['may_be_dead_procentage'] = '0.01'
    params['login'] = login

    mails.send_dm_mail('release_slot ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.release_slots(params)
    return HttpResponse(json.dumps(res))


def release_endpointsets(request):
    login = request.yauser.login if request.yauser.is_authenticated() else 'unauthorized'
    if not is_saas_developer(login):
        return HttpResponseBadRequest(
            json.dumps({'success': False, 'error': 'login ' + login + ' is not saas developer'}))

    params = {}
    param_names = ('service', 'ctype', 'eps')
    for pn in param_names:
        params[pn] = request.GET.get(pn, '')
    if params['service'] in ('searchproxy', 'indexerproxy', 'deploy_manager'):
        params['service_type'] = params['service']
    else:
        params['service_type'] = 'rtyserver'

    params['login'] = login

    mails.send_dm_mail('release_endpointsets ' +
                       params['service'] + '-' + params['ctype'],
                       'cmd=' + json.dumps(params) + '\nlogin=' + login)
    res = cluster.release_endpointsets(params)
    return HttpResponse(json.dumps(res))


def extract_hosts(smap, ctype):
    hosts = []
    for dc, slist in smap[ctype].items():
        for slot in slist:
            if 'gencfg' not in slot['host']:
                hosts.append(slot['host'])
            else:
                try:
                    hosts.append('-'.join(slot['host'].split('-')[:2]) + '.search.yandex.net')
                except:
                    hosts.append(slot['host'])
    return sorted(list(set(hosts)))


def monitor_hosts(request):
    service = request.GET.get('service', '')
    ctype = request.GET.get('ctype')
    if not ctype:
        return HttpResponseBadRequest('service or ctype not set')
    is_service = service not in ('', 'searchproxy', 'indexerproxy', 'deploy_manager')
    is_dm = (service == 'deploy_manager')
    res = {}
    if is_dm:
        smap_dm = cluster.get_used_slots('deploy_manager', ctype)
        if not smap_dm['success']:
            return HttpResponseBadRequest(json.dumps(smap_dm))
        res['deploy_manager'] = extract_hosts(smap_dm['ans'], ctype)
    else:
        smap_sp = cluster.get_used_slots('searchproxy', ctype)
        if not smap_sp['success']:
            return HttpResponseBadRequest(json.dumps(smap_sp))
        res['searchproxy'] = extract_hosts(smap_sp['ans'], ctype)
        smap_ip = cluster.get_used_slots('indexerproxy', ctype)
        if not smap_ip['success']:
            return HttpResponseBadRequest(json.dumps(smap_ip))
        res['indexerproxy'] = extract_hosts(smap_ip['ans'], ctype)
    if is_service:
        smap_be = cluster.get_used_slots(service, ctype)
        if smap_be['success']:
            res['backend'] = extract_hosts(smap_be['ans'], ctype)
    return render_to_response('monitor_hosts.html', {'data': res,
                                                     'ctype': ctype,
                                                     'service_mon': service if is_service else '',
                                                     'service': service})


def get_endpointset(request):
    cluster_eps = request.GET.get('eps')
    yp_cluster, eps = cluster_eps.split('@', 1)
    eps = eps.split(':')[0]
    data = '{"client_name": "saas", "cluster_name": "' + yp_cluster + \
           '", "endpoint_set_id": "' + eps + '"}'
    sd_url = 'http://sd.yandex.net:8080/resolve_endpoints/json'
    try:
        res = urllib2.urlopen(sd_url, data=data.encode('ascii')).read()
    except urllib2.HTTPError as e:
        return HttpResponseBadRequest('smth went wrong: %s , answer %s,  data %s' % (e.code, e.read(), escape(data)))
    except Exception as e:
        return HttpResponseBadRequest('smth went wrong: %s , data %s' % (e, escape(data)))
    return HttpResponse(res)
