import os
import sys
import time
import itertools
import matplotlib.pyplot as plt
import matplotlib.ticker as ticks
import math
from scipy import stats as st
import numpy as np
from enum import Enum
from statistics import median

import matplotlib
matplotlib.use("pgf")
matplotlib.rcParams.update({
    "pgf.texsystem": "pdflatex",
    'font.family': 'serif',
    'text.usetex': True,
    'pgf.rcfonts': False,
    'font.size': 16
})
marker = itertools.cycle(('o', 's', 'D', 'x', 'p', '^', 'h', '*', 'v' )) 

readfile = open(sys.argv[1], "r")

machineName = ""

if len(sys.argv) > 2:
    machineName = sys.argv[2]

# first line has num times per experiment
line = readfile.readline()
numTimes = int(line)

# second line has processor args
line = readfile.readline()
procs = []
for val in line.split():
    procs.append(int(val))

# 3rd line has num locks args
line = readfile.readline()
locks = []
for val in line.split():
    locks.append(int(val))

# 4th line has number of variants
line = readfile.readline()
names = line.split()
numVariants = len(names)

lines = (line.rstrip() for line in readfile) # All lines including the blank ones
lines = (line for line in lines if line) # Non-blank lines

nameSet = False
currLocks = -1 # default val
count = 0
procCount = 0
currVariant = 0
name = "Aggregate Lock"
var_name = ""
experiment_duration = 10.0
sendData = [0.0 for j in range(numVariants)]
data = [[0.0 for i in range(len(procs))] for j in range(numVariants)]
bars = [[[0.0 for i in range(len(procs))],[0.0 for k in range(len(procs))]] for j in range(numVariants)]
tempData = [0.0 for i in range(numTimes)]
for idx, line in enumerate(lines):
    # print(line)
    
    if currLocks == -1:
        lineArr = line.split()
        currLocks = lineArr[-1]
        continue

    if line[0:5] == "cores":
        continue

    if not nameSet:
        nameSet = True
        continue
    
    lineArr = line.split()
    tempData[count] = float(lineArr[-1]) / experiment_duration
    count += 1
    if count == numTimes:
        currMedian = median( tempData )
        data[currVariant][procCount] = currMedian
        lower, upper = st.t.interval(0.95, numTimes - 1, loc=np.mean(tempData), scale=st.sem(tempData))
        bars[currVariant][0][procCount] = max( 0, currMedian - lower )
        bars[currVariant][1][procCount] = max( 0, upper - currMedian )
        count = 0
        procCount += 1

        if procCount == len(procs):
            procCount = 0
            nameSet = False
            currVariant += 1

            if currVariant == numVariants:
                fig, ax = plt.subplots(layout='constrained')
                plt.title(name + " Benchmark: " + str(currLocks) + " Locks")
                plt.ylabel("Throughput (critical section entries per second)")
                plt.xlabel("Cores")
                for idx, arr in enumerate(data):
                    plt.errorbar( procs, arr, [bars[idx][0], bars[idx][1]], capsize=2, marker=next(marker) )
                marker = itertools.cycle(('o', 's', 'D', 'x', 'p', '^', 'h', '*', 'v' )) 
                plt.yscale("log")
                plt.xticks(procs)
                ax.legend(names)
                # fig.savefig("plots/" + machineName + "Aggregate_Lock_" + str(currLocks) + ".png")
                plt.savefig("plots/" + machineName + "Aggregate_Lock_" + str(currLocks) + ".pgf")
                fig.clf()

                # reset
                currLocks = -1
                currVariant = 0