import numpy as np
import psycopg2
import matplotlib
from matplotlib import dates


from time import strftime


from matplotlib.ticker import MultipleLocator

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

matplotlib.use('Agg')


def average_cpu():
    
    import matplotlib.pyplot as plot
    
    db = util.db.connect()
    
    cur = db.cursor()
    
    cur.execute("""
        SELECT * 
            FROM average_core() 
            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 + '/average_cpu.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No cpu data recorded; skipping average_cpu report')
        return
    
    timeseries = [r[0] for r in results]
    peruser = [r[1] for r in results]
    persys = [r[2] for r in results]
    periowait = [r[3] for r in results]
    perhyper = [r[4] for r in results]
    
    hashyper = False
    for h in perhyper:
        if h > 0:
            hashyper = True
            break

    for index, time in enumerate(timeseries):
        timeseries[index] =time.replace(tzinfo=None)
    
    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111)
    hfmt = dates.DateFormatter('%H:%M:%S')

    ax.set_title('Average CPU Utilization')
    ax.set_ylabel('Percentage')
    ax.xaxis.set_major_formatter(hfmt)
    ax.set_ylim(ymin=0, ymax=100)
    ax.set_xlim(xmin=reports.times.graph_sar_start(), xmax=reports.times.graph_sar_end())
    
    ax.plot(timeseries, peruser, color='green', label='User')
    ax.plot(timeseries, persys, color='blue', label='System')
    ax.plot(timeseries, periowait, color='red', label='I/O Wait')
    if hashyper:
        plot.plot(timeseries, perhyper, color='yellow', label='Hypervisor')
    ax.legend(loc='upper right')
    ax.grid(True)
    
    fig.autofmt_xdate()
    
    plot.savefig(REPORT_DIR_PATH + '/average_cpu.pdf')
    plot.close()



def busiest_core():
    
    import matplotlib.pyplot as plot
    
    db = util.db.connect()
    
    cur = db.cursor()
    
    cur.execute("""
        SELECT * 
            FROM busiest_core() 
            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 + '/busiest_core.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No core data recorded; skipping busiest_core report')
        return
    
    timeseries = [r[0] for r in results]
    peruser = [r[1] for r in results]
    persys = [r[2] for r in results]
    periowait = [r[3] for r in results]
    perhyper = [r[4] for r in results]
    
    hashyper = False
    for h in perhyper:
        if h > 0:
            hashyper = True
            break
    
    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)
    ax = fig.add_subplot(111, axisbg='#fafafa', alpha=0.9)
    hfmt = dates.DateFormatter('%H:%M:%S')

    ax.set_title('Busiest Core Utililization')
    ax.set_ylabel('Percentage')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_ylim(ymin=0, ymax=100)
    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())
    
    ax.plot(timeseries, peruser, color='green', label='User')
    ax.plot(timeseries, persys, color='blue', label='System')
    ax.plot(timeseries, periowait, color='red', label='I/O Wait')
    if hashyper:
        plot.plot(timeseries, perhyper, color='yellow', label='Hypervisor')
    ax.legend(loc='upper right')
    ax.grid(True)
    
    fig.autofmt_xdate()
    
    plot.tight_layout()
    
    plot.savefig(REPORT_DIR_PATH + '/busiest_core.pdf')
    plot.close()


def busy_cores():
    
    import matplotlib.pyplot as plot
    from matplotlib.font_manager import FontProperties
    
    small_font = FontProperties()
    small_font.set_size('small')
    
    db = util.db.connect()
    
    cur = db.cursor()
    
    cur.execute("""
        SELECT * 
            FROM busy_cores() 
            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 + '/busy_cores.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No core data recorded; skipping busy_cores report')
        return
    
    timeseries = [r[0] for r in results]
    cores_at_90 = [r[1] for r in results]
    cores_at_75 = [r[2] for r in results]
    cores_at_50 = [r[3] for r in results]
    cores_at_25 = [r[4] for r in results]
    
    cur.execute("""
        SELECT MAX(cpu::INTEGER)+1 FROM cpu WHERE cpu<>'all'
    """)

    total_cores = cur.fetchone()[0]
    
    y = np.row_stack((cores_at_90, cores_at_75, cores_at_50, cores_at_25, ))
    y_stack = np.cumsum(y, axis=0)
    hfmt = dates.DateFormatter('%H:%M:%S')

    fig = plot.figure(figsize=DEFAULT_FIGURE_SIZE)

    ax = fig.add_subplot(111, axisbg='#808080', alpha=0.9)
    
    ax.set_title('Number of Busy Cores')
    ax.set_ylabel('Cores')
    ax.xaxis.set_major_formatter(hfmt)
    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())
    ax.set_ylim(ymin=0, ymax=total_cores)
    ax.yaxis.set_major_locator(MultipleLocator(1))
    
    ax.fill_between(timeseries, 0, y_stack[0,:], linewidth=0, color='red')
    ax.fill_between(timeseries, y_stack[0,:], y_stack[1,:], linewidth=0, color='orange')
    ax.fill_between(timeseries, y_stack[1,:], y_stack[2,:], linewidth=0, color='yellow')
    ax.fill_between(timeseries, y_stack[2,:], y_stack[3,:], linewidth=0, color='green')
    
    a25 = matplotlib.patches.Rectangle((0, 0), 1, 1, color='green')
    a50 = matplotlib.patches.Rectangle((0, 0), 1, 1, color='yellow')
    a75 = matplotlib.patches.Rectangle((0, 0), 1, 1, color='orange')
    a90 = matplotlib.patches.Rectangle((0, 0), 1, 1, color='red')
    
    lgnd = ax.legend((a25, a50, a75, a90), ('25%', '50%', '75%', '90%'), 
        loc='upper right', bbox_to_anchor=(1.15, 1.0), prop=small_font )
    
    ax.grid(True)
    
    fig.autofmt_xdate()
    
    plot.tight_layout()
    
    plot.savefig(REPORT_DIR_PATH + '/busy_cores.pdf', bbox_inches='tight', pad_inches=0.25, bbox_extra_artists=[lgnd])
    plot.close()

def runq_loadavg():

    import matplotlib.pyplot as plot

    db = util.db.connect()

    cur = db.cursor()

    cur.execute("""
        SELECT measurement_time, runq_sz, ldavg_1
            FROM load
            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 + '/busiest_core.txt'
        with open(no_file, 'w') as no_results:
            no_results.write("No results.")
        no_results.close()
        log('No core data recorded; skipping busiest_core report')
        return

    timeseries = [r[0] for r in results]
    runq_sz = [r[1] for r in results]
    load_avg = [r[2] for r in results]

    max_load = 0
    max_que = 0

    for l in load_avg:
        if l > max_load:
            max_load = l
    for q in runq_sz:
        if q > max_que:
            max_que = q

    if max_que > max_load:
        end = max_que+1
    else:
        end = max_load+1



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

    ax.set_title('SERVER LOAD')
    ax.set_ylabel('Size')
    ax.xaxis.set_major_formatter(hfmt)

    ax.set_ylim(ymin=0, ymax=int(end))
    ax.set_xlim(xmin=reports.times.sar_start(), xmax=reports.times.sar_end())

    ax.plot(timeseries, runq_sz, color='green', label='Run queue')
    ax.plot(timeseries, load_avg, color='blue', label='Load Avg ea minute')

    ax.legend(loc='upper right')
    ax.grid(True)

    fig.autofmt_xdate()

    plot.tight_layout()

    plot.savefig(REPORT_DIR_PATH + '/runq_load.pdf')
    plot.close()