#
# Licensed under the Apache License, Version 2.0 (the "License");
# You may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#                       http://www.apache.org/licenses/LICENSE-2.0
#
# Authors:
# - Ralph Vigne, <ralph.vigne@cern.ch> 2015

import json
import locale
import requests
import smtplib
import urllib

from datetime import datetime, timedelta
from email.mime.text import MIMEText

ES_URL = 'cl-analytics.mwt2.org'
SEVERITY_LIST = ['critical', 'error', 'warning', 'info', 'debug']
DATES = [(datetime.today() - timedelta(days=1)).strftime('%Y-%m-%d'), (datetime.today() - timedelta(days=2)).strftime('%Y-%m-%d')]
LINK = ("http://cl-analytics.mwt2.org:5601/#/dashboard/Rucio-Errror-Report?_g=(filters:!(),refreshInterval:(display:Off,pause:!f,section:0,value:0),"
        "time:(from:now-1d%2Fd,mode:quick,to:now-1d%2Fd))&_a=(filters:!((meta:(apply:!t,disabled:!t,index:rucio-daemon-logs,key:severity_label,negate:!f,value:critical),"
        "query:(match:(severity_label:(query:critical,type:phrase)))),(meta:(apply:!t,disabled:!t,index:rucio-daemon-logs,key:severity_label,negate:!f,value:error),"
        "query:(match:(severity_label:(query:error,type:phrase)))),(meta:(apply:!t,disabled:!t,index:rucio-daemon-logs,key:severity_label,negate:!f,value:warning),"
        "query:(match:(severity_label:(query:warning,type:phrase)))),(meta:(apply:!t,disabled:!f,index:rucio-daemon-logs,key:severity_label,negate:!t,value:info),"
        "query:(match:(severity_label:(query:info,type:phrase)))),(meta:(apply:!t,disabled:!f,index:rucio-daemon-logs,key:severity_label,negate:!t,value:debug),"
        "query:(match:(severity_label:(query:debug,type:phrase))))),query:(query_string:(analyze_wildcard:!t,lowercase_expanded_terms:!f,query:'{QUERY}')),title:'Rucio%20-%20Errror%20Report')")

locale.setlocale(locale.LC_ALL, '')


def execute_query(selectors=[]):
    query = {"size": 0, "query": {"filtered": {"filter": {"range": {"@timestamp": {"gte": "now-2d/d", "lte": "now-1d/d"}}}}},
             "aggs": {"daemons": {"terms": {"field": "daemon_raw", "size": 0, "order": {"_term": "asc"}},
                                  "aggs": {"days": {"date_histogram": {"field": "@timestamp", "interval": "day", "format": "yyyy-MM-dd"},
                                                    "aggs": {"severity": {"terms": {"field": "severity_label", "size": 0},
                                                                          "aggs": {"hosts": {"terms": {"field": "host", "size": 0}}}}}}}}}}
    # Adding wildcard to query
    for tup in selectors:
        if 'query' not in query['query']['filtered'].keys():
            query['query']['filtered']['query'] = {"wildcard": {}}
            query['query']['filtered']['query']['wildcard'][tup.keys()[0]] = tup.values()[0]

    # Query data from ES using QueryDSL interface
    resp = requests.post('http://%s:9200/rucio-daemon-logs/_search' % ES_URL, data=json.dumps(query))
    if resp.status_code != 200:
        raise Exception('Failed querying data: %s' % resp.text)
    return json.loads(resp.text)


def html_table_row(tmpDaemon, pp_nodes=False):
    html = ''
    html += '<tr style="border: 1px solid black;">'
    current = DATES[0]
    base = DATES[1]
    query = urllib.quote_plus(('(daemon:%s) AND (host:rucio-daemon-int*)' if pp_nodes else '(daemon:%s)') % tmpDaemon['name'])
    html += '<td><a href="%s">%s</a></td>' % (LINK.replace('{QUERY}', query), tmpDaemon['name'])

    for sl in SEVERITY_LIST:
        delta = tmpDaemon[current][sl] - tmpDaemon[base][sl]
        color = "black"
        if delta > 0:
            color = 'red'
        elif delta < 0:
            color = 'green'
        html += '<td align="center">%s<br/><font color="%s">%s<br/>(%s)</font></td>' % (locale.format("%.0f", tmpDaemon[current][sl], grouping=True),
                                                                                        color,
                                                                                        locale.format("%+.0f", delta, grouping=True),
                                                                                        locale.format("%+.1f", (100.0 / tmpDaemon[base][sl] * delta), grouping=True) + '%' if tmpDaemon[base][sl] != 0 else '-')
    html += '</tr>\n'
    return html


def create_table(buckets, pp_hosts=False):
    html = ''

    html += '<table width="100%" style="border-collapse: collapse; border: 1px solid black;">\n'
    html += '<tr style="border: 1px solid black;">' % ([])
    for sl in (['Daemon'] + SEVERITY_LIST):
        html += '<th>%s</th>' % sl
    html += '</tr>\n'

    tmpDaemon = {'name': buckets[0]['key'].split('-')[0]}
    for date in DATES:
        tmpDaemon[date] = {}
        for sl in SEVERITY_LIST:
            tmpDaemon[date][sl] = 0

    for bDaemon in buckets:
        if tmpDaemon['name'] != bDaemon['key'].split('-')[0]:
            html += html_table_row(tmpDaemon, pp_hosts)
            tmpDaemon = {'name': bDaemon['key'].split('-')[0]}
            for date in DATES:
                tmpDaemon[date] = {}
                for sl in SEVERITY_LIST:
                    tmpDaemon[date][sl] = 0

        for bDate in bDaemon['days']['buckets']:
            if bDate['key_as_string'] not in DATES:
                continue
            for bSeverity in bDate['severity']['buckets']:
                if pp_hosts:
                    for bHost in bSeverity['hosts']['buckets']:
                        if bHost['key'].find('-int-') != -1:
                            tmpDaemon[bDate['key_as_string']][bSeverity['key']] += bHost['doc_count']
                else:
                    tmpDaemon[bDate['key_as_string']][bSeverity['key']] += bSeverity['doc_count']
    html += html_table_row(tmpDaemon)
    html += '</table>\n'
    return html


if __name__ == "__main__":
    buckets = execute_query()['aggregations']['daemons']['buckets']
    html = '<html><body>\n'
    html += '<h2># Total Events (%s)</h2>\n' % (DATES[0])
    html += create_table(buckets)
    html += '<h2># Pre-Production Events (%s)</h2>\n' % (DATES[0])
    html += create_table(buckets, True)
    html += '<h2>Additional Links</h2>'
    html += '<ul>'
    html += '<li><a href="http://cl-analytics.mwt2.org:5601/#/dashboard/Rucio-Daemon-Summary">Rucio - Daemon Summary:</a>&nbsp; general overview of the Rucio daemons</li>'
    html += '</ul>'
    html += '</body></html>\n'

    msg = MIMEText(html, 'html')

    msg['Subject'] = '[RUCIO] Daemon Activity Report'
    msg['From'] = 'rucio-dev@cern.ch'
    msg['To'] = 'rucio-dev@cern.ch; atlas-adc-ddm-support@cern.ch'

    # Send the message via our own SMTP server, but don't include the
    # envelope header.
    s = smtplib.SMTP('localhost')
    s.sendmail('rucio-dev@cern.ch', ['rucio-dev@cern.ch', 'atlas-adc-ddm-support@cern.ch'], msg.as_string())
