import argparse
from collections import OrderedDict
import sys

from chart import charts



OPERATIONS = (('async', ('randwrite asynchronous', 'randread asynchronous',
                         'write asynchronous', 'read asynchronous')),
              ('sync', ('randwrite synchronous', 'randread synchronous',
                        'write synchronous', 'read synchronous')))

sync_async_view = {'s': 'synchronous',
                   'a': 'asynchronous'}


def ssize_to_kb(ssize):
    try:
        smap = dict(k=1, K=1, M=1024, m=1024, G=1024**2, g=1024**2)
        for ext, coef in smap.items():
            if ssize.endswith(ext):
                return int(ssize[:-1]) * coef

        if int(ssize) % 1024 != 0:
            raise ValueError()

        return int(ssize) / 1024

    except (ValueError, TypeError, AttributeError):
        tmpl = "Unknow size format {0!r} (or size not multiples 1024)"
        raise ValueError(tmpl.format(ssize))


def parse_args(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('-s', '--storage', help='storage location', dest="url")
    parser.add_argument('-e', '--email', help='user email',
                        default="aaa@gmail.com")
    parser.add_argument('-p', '--password', help='user password',
                        default="1234")
    return parser.parse_args(argv)


def build_vertical_bar(results):
    data = {}
    charts_url = []

    for build, results in results.items():
        for key, value in results.results.items():
            keys = key.split(' ')
            if not data.get(keys[2]):
                data[keys[2]] = {}
            if not data[keys[2]].get(build):
                data[keys[2]][build] = {}
            data[keys[2]][build][
                ' '.join([keys[0], sync_async_view[keys[1]]])] = value

    for name, value in data.items():
        for op_type, operations in OPERATIONS:
            title = "Block size: " + name
            legend = []
            dataset = []

            scale_x = []

            for build_id, build_results in value.items():
                vals = []

                for key in operations:
                    res = build_results.get(key)
                    if res:
                        vals.append(res)
                        scale_x.append(key)
                if vals:
                    dataset.append(vals)
                    legend.append(build_id)

            if dataset:
                charts_url.append(str(charts.render_vertical_bar
                                  (title, legend, dataset, scale_x=scale_x)))
    return charts_url


def build_lines_chart(results):
    data = {}
    charts_url = []

    for build, results in results.items():
        for key, value in results.results.items():
            keys = key.split(' ')
            if not data.get(' '.join([keys[0], keys[1]])):
                data[' '.join([keys[0], keys[1]])] = {}
            if not data[' '.join([keys[0], keys[1]])].get(build):
                data[' '.join([keys[0], keys[1]])][build] = {}
            data[' '.join([keys[0], keys[1]])][build][keys[2]] = value

    for name, value in data.items():
        title = name
        legend = []
        dataset = []
        scale_x = []
        for build_id, build_results in value.items():
            legend.append(build_id)

            OD = OrderedDict
            ordered_build_results = OD(sorted(build_results.items(),
                                       key=lambda t: ssize_to_kb(t[0])))

            if not scale_x:
                scale_x = ordered_build_results.keys()
            dataset.append(zip(*ordered_build_results.values())[0])

        chart = charts.render_lines(title, legend, dataset, scale_x)
        charts_url.append(str(chart))

    return charts_url


def render_html(charts_urls):
    templ = open("report.html", 'r').read()
    body = "<div><ol>%s</ol></div>"
    li = "<li><img src='%s'></li>"
    ol = []
    for chart in charts_urls:
        ol.append(li % chart)
    html = templ % {'body': body % '\n'.join(ol)}
    open('results.html', 'w').write(html)


# def report(url, email=None, password=None):
#     results = storage.recent_builds()
#     bars = build_vertical_bar(results)
#     lines = build_lines_chart(results)
#
#     render_html(bars + lines)

#
# def main(argv):
#     opts = parse_args(argv)
#     report(opts.url)
#     return 0
#
#
# if __name__ == '__main__':
#     exit(main(sys.argv[1:]))
