
from .formats import GolovanInput
from .dm import SIGNALS

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

GOLOVAN_API = 'http://yasm.yandex-team.ru/srvambry/alerts/'


def do_retries(url, data):
    error = None
    success = False
    answer = ''
    data_enc = data.encode('ascii') if data else None
    for i in range(3):
        try:
            answer = urllib2.urlopen(url, data=data_enc).read().decode('utf-8')
            success = True
            break
        except urllib2.HTTPError as e:
            answer = e.read()
            error = e
            if e.code < 500:
                break
        except Exception as e:
            error = e
    return {'success': success, 'error': '%s' % error, 'answer': answer}


def golovan_send(golovan_input):
    if not isinstance(golovan_input, GolovanInput):
        raise Exception('incorrect golovan_input type')
    data = json.dumps(golovan_input.to_json())
    result = do_retries(GOLOVAN_API + 'update?name=' + golovan_input.GolovanId, data)
    if not result['success']:
        result = do_retries(GOLOVAN_API + 'create?name=' + golovan_input.GolovanId, data)
    return result


def golovan_patch(alert_ids, fields):
    data = json.dumps(fields)
    result = {}
    result_err = {}
    for alert_id in alert_ids:
        result = do_retries(GOLOVAN_API + 'patch?name=' + alert_id, data)
        if not result['success']:
            result_err = result.copy()
    return result_err or result


def golovan_get(args_dict):
    url = GOLOVAN_API + 'list?'
    url += urllib.parse.urlencode(args_dict, True)
    result = do_retries(url, None)
    return result


def golovan_delete(alert_name):
    url = GOLOVAN_API + 'delete?name=' + alert_name
    result = do_retries(url, '')
    return result


def alert_ctype_from_name(alert_id):
    return alert_id.split('.')[2] if len(alert_id.split('.')) > 2 else 'unknown_ctype'


def alert_service_from_name(alert_id):
    return alert_id.split('.')[3] if len(alert_id.split('.')) > 3 else 'unknown_service'


def alert_key_from_name(alert_id):
    akeys = [ak for ak in SIGNALS().keys() if ak in alert_id.split('.')]
    return akeys[0] if akeys else 'unknown_key'


def get_all_alerts_names():
    alerts_ans = golovan_get({'name_prefix': 'saas.gen'})
    if not alerts_ans['success']:
        return alerts_ans
    alerts = json.loads(alerts_ans['answer'])['response']['result']
    al_names = [al['name'] for al in alerts]
    return {'success': True, 'alerts': al_names}


def alerts_by_ctype_service(input=None, use_input=False):
    if not input and not use_input:
        alerts_res = get_all_alerts_names()
        if not alerts_res['success']:
            return alerts_res
        alerts = alerts_res['alerts']
    else:
        alerts = input
    res = {}
    for alert in alerts:
        try:
            al_name = alert['name']
        except:
            al_name = alert
        ctype = alert_ctype_from_name(al_name)
        service = alert_service_from_name(al_name)
        res[ctype] = res.get(ctype, {})
        res[ctype][service] = res[ctype].get(service, {})
        skey = alert_key_from_name(al_name)
        res[ctype][service][skey] = res[ctype][service].get(skey, [])
        res[ctype][service][skey].append(al_name)
    return {'success': True, 'alerts': res}
