import os
import bisect
import logging

try:
    import matplotlib.pyplot as plt
except ImportError:
    plt = None

import wally
from wally import charts
from wally.statistic import round_3_digit
from wally.utils import parse_creds, ssize_to_b
from wally.suits.io.results_loader import process_disk_info
from wally.meta_info import total_lab_info, collect_lab_data


logger = logging.getLogger("wally.report")


class DiskInfo(object):
    def __init__(self):
        self.direct_iops_r_max = 0
        self.direct_iops_w_max = 0
        self.rws4k_10ms = 0
        self.rws4k_30ms = 0
        self.rws4k_100ms = 0
        self.bw_write_max = 0
        self.bw_read_max = 0


report_funcs = []


def report(name, required_fields):
    def closure(func):
        report_funcs.append((required_fields.split(","), name, func))
        return func
    return closure


# def linearity_report(processed_results, path, lab_info):
#     names = {}
#     for tp1 in ('rand', 'seq'):
#         for oper in ('read', 'write'):
#             for sync in ('sync', 'direct', 'async'):
#                 sq = (tp1, oper, sync)
#                 name = "{0} {1} {2}".format(*sq)
#                 names["".join(word[0] for word in sq)] = name

#     colors = ['red', 'green', 'blue', 'cyan',
#               'magenta', 'black', 'yellow', 'burlywood']
#     markers = ['*', '^', 'x', 'o', '+', '.']
#     color = 0
#     marker = 0

#     name_pref = 'linearity_test_'
#     plot_data = []

#     x = []
#     y = []
#     e = []
#     # values to make line
#     ax = []
#     ay = []

#     for res in processed_results.values():
#         if res.name.startswith(name_pref):
#             res

#     for sz, med, dev in sorted(filtered_data(data)):
#         iotime_ms = 1000. // med
#         iotime_max = 1000. // (med - dev * 3)

#         x.append(sz / 1024.0)
#         y.append(iotime_ms)
#         e.append(iotime_max - iotime_ms)
#         if vals is None or sz in vals:
#             ax.append(sz / 1024.0)
#             ay.append(iotime_ms)

#     plt.errorbar(x, y, e, linestyle='None', label=names[tp],
#                  color=colors[color], ecolor="black",
#                  marker=markers[marker])
#     ynew = approximate_line(ax, ay, ax, True)
#     plt.plot(ax, ynew, color=colors[color])
#     color += 1
#     marker += 1
#     plt.legend(loc=2)
#     plt.title("Linearity test by %i dots" % (len(vals)))


# if plt:
#     linearity_report = report('linearity', 'linearity_test')(linearity_report)


def render_hdd_html(dest, info, lab_description):
    very_root_dir = os.path.dirname(os.path.dirname(wally.__file__))
    templ_dir = os.path.join(very_root_dir, 'report_templates')
    templ_file = os.path.join(templ_dir, "report_hdd.html")
    templ = open(templ_file, 'r').read()

    for name in info.__dict__:
        if not name.startswith('__'):
            if info.__dict__[name] == "-":
                continue
            info.__dict__[name] = round_3_digit(info.__dict__[name])

    report = templ.format(lab_info=lab_description, **info.__dict__)
    open(dest, 'w').write(report)


def render_ceph_html(dest, info, lab_description):
    very_root_dir = os.path.dirname(os.path.dirname(wally.__file__))
    templ_dir = os.path.join(very_root_dir, 'report_templates')
    templ_file = os.path.join(templ_dir, "report_ceph.html")
    templ = open(templ_file, 'r').read()

    for name, val in info.__dict__.items():
        if not name.startswith('__') and isinstance(val, (int, long, float)):
            setattr(info, name, round_3_digit(val))

    report = templ.format(lab_info=lab_description, **info.__dict__)
    open(dest, 'w').write(report)


def io_chart(title, concurence, latv, iops_or_bw, iops_or_bw_dev,
             legend, fname):
    bar_data, bar_dev = iops_or_bw, iops_or_bw_dev
    legend = [legend]

    iops_or_bw_per_vm = []
    for i in range(len(concurence)):
        iops_or_bw_per_vm.append(iops_or_bw[i] / concurence[i])

    bar_dev_bottom = []
    bar_dev_top = []
    for i in range(len(bar_data)):
        bar_dev_top.append(bar_data[i] + bar_dev[i])
        bar_dev_bottom.append(bar_data[i] - bar_dev[i])

    latv = [lat / 1000 for lat in latv]
    ch = charts.render_vertical_bar(title, legend, [bar_data], [bar_dev_top],
                                    [bar_dev_bottom], file_name=fname,
                                    scale_x=concurence, label_x="clients",
                                    label_y="iops",
                                    lines=[
                                        (latv, "msec", "rr", "lat"),
                                        (iops_or_bw_per_vm, None, None,
                                         legend[0] + " per thread")
                                    ])
    return str(ch)


def make_hdd_plots(processed_results, path):
    plots = [
        ('hdd_test_rrd4k', 'rand_read_4k', 'Random read 4k direct IOPS'),
        ('hdd_test_rws4k', 'rand_write_4k', 'Random write 4k sync IOPS')
    ]
    make_plots(processed_results, path, plots)


def make_ceph_plots(processed_results, path):
    plots = [
        ('ceph_test_rrd4k', 'rand_read_4k', 'Random read 4k direct IOPS'),
        ('ceph_test_rws4k', 'rand_write_4k', 'Random write 4k sync IOPS'),
        ('ceph_test_rrd16m', 'rand_read_16m', 'Random read 16m direct MiBps'),
        ('ceph_test_swd1m', 'seq_write_1m',
            'Sequential write 1m direct MiBps'),
    ]
    make_plots(processed_results, path, plots)


def make_plots(processed_results, path, plots):
    for name_pref, fname, desc in plots:
        chart_data = []

        for res in processed_results.values():
            if res.name.startswith(name_pref):
                chart_data.append(res)

        if len(chart_data) == 0:
            raise ValueError("Can't found any date for " + name_pref)

        use_bw = ssize_to_b(chart_data[0].raw['blocksize']) > 16 * 1024

        chart_data.sort(key=lambda x: x.raw['concurence'])

        lat = [x.lat for x in chart_data]
        vm_count = x.meta['testnodes_count']
        concurence = [x.raw['concurence'] * vm_count for x in chart_data]

        if use_bw:
            data = [x.bw for x in chart_data]
            data_dev = [x.bw * x.dev for x in chart_data]
            name = "BW"
        else:
            data = [x.iops for x in chart_data]
            data_dev = [x.iops * x.dev for x in chart_data]
            name = "IOPS"

        io_chart(desc, concurence, lat, data, data_dev, name, fname)


def get_disk_info(processed_results):
    di = DiskInfo()
    rws4k_iops_lat_th = []

    for res in processed_results.values():
        if res.raw['sync_mode'] == 'd' and res.raw['blocksize'] == '4k':
            if res.raw['rw'] == 'randwrite':
                di.direct_iops_w_max = max(di.direct_iops_w_max, res.iops)
            elif res.raw['rw'] == 'randread':
                di.direct_iops_r_max = max(di.direct_iops_r_max, res.iops)
        elif res.raw['sync_mode'] == 's' and res.raw['blocksize'] == '4k':
            if res.raw['rw'] != 'randwrite':
                continue

            rws4k_iops_lat_th.append((res.iops, res.lat,
                                      res.raw['concurence']))

        elif res.raw['sync_mode'] == 'd' and res.raw['blocksize'] == '1m':

            if res.raw['rw'] == 'write':
                di.bw_write_max = max(di.bw_write_max, res.bw)
            elif res.raw['rw'] == 'read':
                di.bw_read_max = max(di.bw_read_max, res.bw)
        elif res.raw['sync_mode'] == 'd' and res.raw['blocksize'] == '16m':
            if res.raw['rw'] == 'write' or res.raw['rw'] == 'randwrite':
                di.bw_write_max = max(di.bw_write_max, res.bw)
            elif res.raw['rw'] == 'read' or res.raw['rw'] == 'randread':
                di.bw_read_max = max(di.bw_read_max, res.bw)

    di.bw_write_max /= 1000
    di.bw_read_max /= 1000

    rws4k_iops_lat_th.sort(key=lambda (_1, _2, conc): conc)

    latv = [lat for _, lat, _ in rws4k_iops_lat_th]

    for tlatv_ms in [10, 30, 100]:
        tlat = tlatv_ms * 1000
        pos = bisect.bisect_left(latv, tlat)
        if 0 == pos:
            iops3 = 0
        elif pos == len(latv):
            iops3 = latv[-1]
        else:
            lat1 = latv[pos - 1]
            lat2 = latv[pos]

            th1 = rws4k_iops_lat_th[pos - 1][2]
            th2 = rws4k_iops_lat_th[pos][2]

            iops1 = rws4k_iops_lat_th[pos - 1][0]
            iops2 = rws4k_iops_lat_th[pos][0]

            th_lat_coef = (th2 - th1) / (lat2 - lat1)
            th3 = th_lat_coef * (tlat - lat1) + th1

            th_iops_coef = (iops2 - iops1) / (th2 - th1)
            iops3 = th_iops_coef * (th3 - th1) + iops1
        setattr(di, 'rws4k_{}ms'.format(tlatv_ms), int(iops3))

    hdi = DiskInfo()
    hdi.direct_iops_r_max = di.direct_iops_r_max
    hdi.direct_iops_w_max = di.direct_iops_w_max
    hdi.rws4k_10ms = di.rws4k_10ms if 0 != di.rws4k_10ms else '-'
    hdi.rws4k_30ms = di.rws4k_30ms if 0 != di.rws4k_30ms else '-'
    hdi.rws4k_100ms = di.rws4k_100ms if 0 != di.rws4k_100ms else '-'
    hdi.bw_write_max = di.bw_write_max
    hdi.bw_read_max = di.bw_read_max
    return hdi


@report('HDD', 'hdd_test_rrd4k,hdd_test_rws4k')
def make_hdd_report(processed_results, path, lab_info):
    make_hdd_plots(processed_results, path)
    di = get_disk_info(processed_results)
    render_hdd_html(path, di, lab_info)


@report('Ceph', 'ceph_test')
def make_ceph_report(processed_results, path, lab_info):
    make_ceph_plots(processed_results, path)
    di = get_disk_info(processed_results)
    render_ceph_html(path, di, lab_info)


def make_io_report(results, path, lab_url=None, creds=None):
    if lab_url is not None:
        username, password, tenant_name = parse_creds(creds)
        creds = {'username': username,
                 'password': password,
                 "tenant_name": tenant_name}
        data = collect_lab_data(lab_url, creds)
        lab_info = total_lab_info(data)
    else:
        lab_info = {
            "total_disk": "None",
            "total_memory": "None",
            "nodes_count": "None",
            "processor_count": "None"
        }

    try:
        processed_results = process_disk_info(results)
        res_fields = sorted(processed_results.keys())
        for fields, name, func in report_funcs:
            for field in fields:
                pos = bisect.bisect_left(res_fields, field)

                if pos == len(res_fields):
                    break

                if not res_fields[pos].startswith(field):
                    break
            else:
                hpath = path.format(name)
                logger.debug("Generatins report " + name + " into " + hpath)
                func(processed_results, hpath, lab_info)
                break
        else:
            logger.warning("No report generator found for this load")

    except Exception as exc:
        import traceback
        traceback.print_exc()
        logger.error("Failed to generate html report:" + str(exc))
