import sys
import urllib2
import threading
import Queue
import functools
import logging
import json
import flask

from lxml import etree
from collections import defaultdict

import library.python.init_log as lpi


logger = logging.getLogger('solomon')
app = flask.Flask(__name__)


def parse_one(data):
    r = defaultdict(float)

    for e in etree.fromstring(data).iter():
        try:
            a = e.attrib['stats_attr']

            if '_medians' in a:
                pass
            else:
                r[a + ':' + e.tag] += float(e.text)
        except KeyError:
            pass

    return r


def fetch_one(url):
    if url.startswith('http'):
        data = urllib2.urlopen(url, timeout=10).read()
    else:
        with open(url, 'r') as f:
            data = f.read()

    return parse_one(data)


def calc_stats(urls):
    stats = defaultdict(long)
    thrs = []
    q = Queue.Queue()

    def do_fetch(url):
        try:
            q.put(fetch_one(url))
        except Exception as e:
            logger.error('in do_fetch(): %s', e)

    for url in urls:
        thrs.append(threading.Thread(target=functools.partial(do_fetch, url)))

    for t in thrs:
        t.start()

    for t in thrs:
        t.join()

    while True:
        try:
            for k, v in q.get(block=False).items():
                stats[k] += v
        except Queue.Empty:
            break

    return stats


@app.route('/stats_ruchka')
def stats_ruchka():
    def do():
        for k, v in calc_stats(app.cfg['urls']).items():
            d = {
                'value': v,
                'mode': 'deriv',
            }

            l = k.split(':')

            labels = {
                'role': l[0],
                'sensor': '/' + '/'.join(l),
            }

            for n, i in enumerate(l[1:]):
                labels['label' + str(1 + n)] = i

            d['labels'] = labels

            yield d

    return json.dumps({'sensors': list(do())}, indent=4, sort_keys=True)


if __name__ == '__main__':
    verbose = '-v' in sys.argv

    lpi.init_log(level='DEBUG' if verbose else 'INFO')

    logger.info('at your service')

    with open(sys.argv[1], 'r') as f:
        app.cfg = json.loads(f.read())

    app.run(port=long(app.cfg['port']), debug=False, host='::')
