import numpy as np
import matplotlib
from matplotlib.font_manager import FontProperties
from matplotlib import dates

import psycopg2

from config.settings import *
from settings import *
import util.db
from util.log import log
import reports.times

matplotlib.use('Agg')
    
def disk_activity_by_device(device, name):

    import matplotlib.pyplot as plot
    
    db = util.db.connect()

    cur = db.cursor()
    
    if not isinstance(device, (list, tuple)):
        device = ( device, )
    elif isinstance(device, list):
        device = tuple(device)
    
    cur.execute("""
        SELECT measurement_time, SUM(mb_rd_sec), SUM(mb_wr_sec) FROM disk_activity() 
            WHERE dev IN %(device)s AND
                  measurement_time BETWEEN %(start_time)s AND %(end_time)s
            GROUP BY measurement_time
            ORDER BY measurement_time
        """, reports.times.sar_range({ 'device': device }) )

    results = cur.fetchall()

    if not results:
        no_file = REPORT_DIR_PATH + '/disk_activity_by_device.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No disk activity recorded; skipping disk_activity_by_device report')
        return
    
    timeseries = [r[0] for r in results]
    mb_rd_sec = [r[1] for r in results]
    mb_wr_sec = [r[2] for r in results]

    if len(timeseries) == 0:
        log("No measurements, so no disk activity report for "+name)
        return
            
    if not (max(mb_rd_sec) or max(mb_wr_sec)):
        log("No mb_rd_sec or mb_wr_sec greater than zero, so no disk activity report for "+name)
        return
        
    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    ax.plot(timeseries, mb_rd_sec, color='blue', label='Read')
    ax.plot(timeseries, mb_wr_sec, color='red', label='Write')
   
    small_font = FontProperties()
    small_font.set_size('small')
    
    ax.set_title('Disk Activity (' + name + ')')
    
    ax.set_ylabel('Megabytes per Second')
    
    ax.legend(loc='upper right')

    ax.grid(True)
    
    fig.autofmt_xdate()
    
    plot.savefig(REPORT_DIR_PATH + '/disk_activity-' + name + '.pdf' )

    plot.close()


def disk_activity():
    for name, devices in DEVICES.iteritems():
        disk_activity_by_device(devices, name)


def service_wait_by_device(device, name):

    import matplotlib.pyplot as plot
    
    db = util.db.connect()

    cur = db.cursor()
    
    if not isinstance(device, (list, tuple)):
        device = ( device, )
    elif isinstance(device, list):
        device = tuple(device)
    
    cur.execute("""
        SELECT measurement_time, MAX(await), MAX(avgqu_s), MAX(perutil)
            FROM disk 
            WHERE dev IN %(device)s AND
                  measurement_time BETWEEN %(start_time)s AND %(end_time)s
            GROUP BY measurement_time
            ORDER BY measurement_time
        """, reports.times.sar_range({ 'device': device }) )

    results = cur.fetchall()

    if not results:
        no_file = REPORT_DIR_PATH + '/service_wait_by_device.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No service wait data recorded; skipping service_wait_by_device report')
        return
    
    timeseries = [r[0] for r in results]
    await = [r[1] for r in results]
    avgqu_s = [r[2] for r in results]
    perutil = [r[3] for r in results]

    if len(timeseries) == 0:
        log("No measurements, so no service wait report for "+name)
        return
            
    small_font = FontProperties()
    small_font.set_size('small')
    
    fig = plot.figure(1, figsize=(DEFAULT_FIGURE_SIZE[0], DEFAULT_FIGURE_SIZE[1]*2))
    
    axa = fig.add_subplot(311, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')
    axa.xaxis.set_major_formatter(hfmt)

    axa.set_title('Service Wait Time (' + name + ')')
        
    axa.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    axa.plot(timeseries, await, color='red', label='Wait Time')
   
    axa.set_ylabel('Milliseconds')
    
    fig.autofmt_xdate()
    
    axu = fig.add_subplot(312, axisbg='#fafafa', alpha=0.9)
    axu.xaxis.set_major_formatter(hfmt)

    axu.set_title('Queue Length (' + name + ')')
    axu.set_ylabel('Requests')

    axu.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    axu.plot(timeseries, avgqu_s, color='orange', label='Percentage Utilization')

    fig.autofmt_xdate()
    
    axp = fig.add_subplot(313, axisbg='#fafafa', alpha=0.9)
    axp.set_title('Percent Utilization (' + name + ')')
    axp.set_ylabel('Percent')
    axp.xaxis.set_major_formatter(hfmt)

    axp.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    axp.plot(timeseries, perutil, color='blue', label='Wait Time')
   
    fig.autofmt_xdate()
    
    plot.savefig(REPORT_DIR_PATH + '/service_wait-' + name + '.pdf' )

    plot.close()


def service_wait():
    for name, devices in DEVICES.iteritems():
        service_wait_by_device(devices, name)


def io_wait():
    
    import matplotlib.pyplot as plot
    
    db = util.db.connect()
    
    cur = db.cursor()
    
    cur.execute("""
        SELECT measurement_time, avg_io_wait, max_io_wait
            FROM io_wait()
            WHERE measurement_time BETWEEN %(start_time)s AND %(end_time)s
            ORDER BY measurement_time
        """, reports.times.sar_range())
    
    results = cur.fetchall()

    if not results:
        no_file = REPORT_DIR_PATH + '/io_wait.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No io data recorded; skipping io_wait report')
        return
    
    timeseries = [r[0] for r in results]
    avg_io_wait = [r[1] for r in results]
    max_io_wait = [r[2] for r in results]
    
    if len(timeseries) == 0:
        log("No measurements, so no I/O wait report.")
        return
            
    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    ax.plot(timeseries, avg_io_wait, color='blue', label='Average')
    ax.plot(timeseries, max_io_wait, color='red', label='Maximum')
    
    small_font = FontProperties()
    small_font.set_size('small')
    
    ax.set_title('I/O Wait')
    
    ax.set_ylabel('Percent')
    
    ax.grid(True)
    
    ax.legend(loc='upper right')
    
    fig.autofmt_xdate()
    
    plot.savefig(REPORT_DIR_PATH + '/io_wait.pdf')

    plot.close()


def tps_activity_by_device(device, name):

    import matplotlib.pyplot as plot

    db = util.db.connect()

    cur = db.cursor()

    if not isinstance(device, (list, tuple)):
        device = ( device, )
    elif isinstance(device, list):
        device = tuple(device)

    cur.execute("""
        SELECT measurement_time, tps FROM disk
            WHERE dev IN %(device)s AND
                  measurement_time BETWEEN %(start_time)s AND %(end_time)s
            ORDER BY measurement_time
        """, reports.times.sar_range({ 'device': device }) )

    results = cur.fetchall()

    if not results:
        no_file = REPORT_DIR_PATH + '/disk_activity_by_device.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No disk activity recorded; skipping disk_activity_by_device report')
        return

    timeseries = [r[0] for r in results]
    tps = [r[1] for r in results]

    if len(timeseries) == 0:
        log("No measurements, so no disk activity report for "+name)
        return


    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    ax.plot(timeseries, tps, color='red', label='TPS')

    small_font = FontProperties()
    small_font.set_size('small')

    ax.set_title('Transactions Per Second (' + name + ')')

    ax.set_ylabel('TPS')

    ax.legend(loc='upper right')

    ax.grid(True)

    fig.autofmt_xdate()

    plot.savefig(REPORT_DIR_PATH + '/tps_activity-' + name + '.pdf' )

    plot.close()

def tps_activity():
    for name, devices in DEVICES.iteritems():
        tps_activity_by_device(devices, name)


def paging():

    import matplotlib.pyplot as plot

    db = util.db.connect()

    cur = db.cursor()

    cur.execute("""
        SELECT measurement_time, pg_in_s, pg_out_s FROM paging
            WHERE measurement_time BETWEEN %(start_time)s AND %(end_time)s
            ORDER BY measurement_time
        """, reports.times.sar_range())

    results = cur.fetchall()

    if not results:
        no_file = REPORT_DIR_PATH + '/paging.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No paging activity recorded; skipping disk_activity_by_device report')
        return

    timeseries = [r[0] for r in results]
    kb_pgin_sec = [r[1] for r in results]
    kb_pgout_sec = [r[2] for r in results]

    if len(timeseries) == 0:
        log("No measurements, so no disk activity report")
        return

    if not (max(kb_pgin_sec) or max(kb_pgout_sec)):
        log("No kb_pgin_sec or kb_pgout_sec greater than zero, so no paging activity")
        return

    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    ax.plot(timeseries, kb_pgin_sec, color='blue', label='Read')
    ax.plot(timeseries, kb_pgout_sec, color='red', label='Write')

    small_font = FontProperties()
    small_font.set_size('small')

    ax.set_title('Filesystem Cache Paging')

    ax.set_ylabel('Kilobytes per Second')

    ax.legend(loc='upper right')

    ax.grid(True)

    fig.autofmt_xdate()

    plot.savefig(REPORT_DIR_PATH + '/paging' + '.pdf' )

    plot.close()