#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, sys
sys.path.append(os.path.abspath(os.path.dirname(os.path.abspath(__file__))+"/../scripts"))

import fileinput
import numpy as np
import matplotlib as mpl
import re

show = False
if len(sys.argv) > 1 and sys.argv[1] == 'show':
	show = True

if not show:
	mpl.use('pgf')

import matplotlib.pyplot as plt
from common import set_size, config_plt, get_colors

config_plt()


def loadData(fn):
	content = []

	with open(fn) as f:
		content = f.readlines()

	zipcontent = zip(content[0::3], content[1::3], content[2::3])

	values = {}
	for lconf, ltime, lresult in zipcontent:
		match = re.search(r"f: [a-z_]*_([a-z]+).*grasp: ([0-9]+), outer: ([0-9]+), inner: ([0-9]+).*threads: (\d+)", lconf)
		if match:
			method = match.group(1)
			grasp_n = int(match.group(2))
			outer = int(match.group(3))
			inner = int(match.group(4))
			ncores = int(match.group(5))

		match = re.search(r"user ([^ ]+) sys (.*)$", ltime)
		if match:
			user = float(match.group(1))
			sys = float(match.group(2))

		if method == 'firstlevel':
			time = (user+sys) / min(ncores, grasp_n)
		else:
			time = (user+sys) / ncores

		if not ncores in values:
			values[ncores] = []
		values[ncores].append(time);

	return values


def exportLegend(legend, filename):
	fig = legend.figure
	fig.canvas.draw()
	fig.savefig(filename, format='pdf', bbox_inches=legend.get_window_extent().transformed(fig.dpi_scale_trans.inverted()))


def figSeq(title, xlabel, rotation, output, datasrcs, scale, error=False):
	fig = plt.figure()

	plt.title(title)
	plt.xlabel(xlabel)
	plt.ylabel(u"time (s)")

	nd = len(datasrcs)
	labels = [datasrc[1] for datasrc in datasrcs]
	plt.xticks(range(len(labels)), labels, rotation=rotation, ha='right')

	width = 0.5
	pos = .5-.5*nd
	x = 0
	for f, label in datasrcs:
		values = loadData(f)
		barcolor, errcolor = get_colors(labels, label)

		for k, a in values.items():
			m = np.mean(a)
			s = 2.5758 * np.std(a) / np.sqrt(len(a))  # confiance 99 %

			plt.bar(x, m, width=width, color=barcolor, label=label)
			if error:
				plt.errorbar(x, m, s, elinewidth=2, capsize=4, ecolor=errcolor)
			label=''

		pos = pos + 1
		x = x+1

	fig.set_size_inches(set_size(455.24408, scale))

	if not show:
		fig.savefig(output, format='pdf', bbox_inches='tight')
	return plt


def figCores(title, xlabel, xticks, output, datasrcs, scale, ycor=np.NaN, legendfile='', error=False):
	fig = plt.figure()

	plt.title(title)
	plt.xlabel(xlabel)
	plt.ylabel(u"time (s)")
	plt.xticks(xticks)

	if not np.isnan(ycor):
		plt.gca().yaxis.set_label_coords(ycor, .5)

	nd = len(datasrcs)
	labels = [datasrc[1] for datasrc in datasrcs]

	width = 0.16
	pos = .5-.5*nd
	for f, label in datasrcs:
		values = loadData(f)
		barcolor, errcolor = get_colors(labels, label)

		for k, a in values.items():
			x = int(k)
			m = np.mean(a)
			s = 2.5758 * np.std(a) / np.sqrt(len(a))  # confiance 99 %

			x = x + pos*width

			plt.bar(x, m, width=width, color=barcolor, label=label)
			if error:
				plt.errorbar(x, m, s, elinewidth=.6, capsize=.6, ecolor=errcolor)
			label=''

		pos = pos + 1

	fig.set_size_inches(set_size(455.24408, scale))

	bbox = (.9, .88)
	if legendfile != '': # isolation of the legend
		bbox = (2, 2)

	#  legend = fig.legend(bbox_to_anchor=bbox)
	#  if legendfile != '':
		#  if legendfile != 'x':
			#  exportLegend(legend, legendfile)
		#  legend.remove()

	if not show:
		fig.savefig(output, format='pdf', bbox_inches='tight')
	return plt


def figCoresSpeedup(title, xlabel, xticks, output, basetime, datasrcs, scale, legendfile=''):
	fig = plt.figure()

	plt.title(title)
	plt.xlabel(xlabel)
	plt.ylabel(u"speed up")
	plt.xticks(xticks)

	plt.gca().yaxis.set_label_coords(-.105, .5)

	nd = len(datasrcs)
	labels = [datasrc[1] for datasrc in datasrcs]

	width = 0.25
	pos = .5-.5*nd
	for f, label in datasrcs:
		values = loadData(f)
		barcolor, errcolor = get_colors(labels, label)

		if 1 in values:
			values.pop(1)

		for k, a in values.items():
			x = int(k)
			m = basetime/np.mean(a)

			x = x + pos*width

			plt.bar(x, m, width=width, color=barcolor, label=label)
			label=''

		pos = pos + 1

	fig.set_size_inches(set_size(455.24408, scale))

	bbox = (.485, .88)
	if legendfile != '': # isolation of the legend
		bbox = (2, 2)

	#  legend = fig.legend(bbox_to_anchor=bbox)
	#  if legendfile != '':
		#  if legendfile != 'x':
			#  exportLegend(legend, legendfile)
		#  legend.remove()

	if not show:
		fig.savefig(output, format='pdf', bbox_inches='tight')
	return plt


def figSizeSpeedup(title, xlabel, xticks, output, basetimes, cores, datasrcs, scale, legendfile=''):
	fig = plt.figure()

	plt.title(title)
	plt.xlabel(xlabel)
	plt.ylabel(u"speed up")
	plt.xticks(xticks)

	plt.gca().yaxis.set_label_coords(-.11, .5)

	nd = len(datasrcs)
	labels = [datasrc[1] for datasrc in datasrcs]

	width = 0.5
	pos = .5-.5*nd
	for fs, label in datasrcs:
		barcolor, errcolor = get_colors(labels, label)

		xi = 0
		for f in fs:
			valuesAllCores = loadData(f)
			values = valuesAllCores[cores]

			x = xticks[xi]
			m = basetimes[xi]/np.mean(values)

			x = x + pos*width

			plt.bar(x, m, width=width, color=barcolor, label=label)
			label=''

			xi = xi + 1

		pos = pos + 1

	fig.set_size_inches(set_size(455.24408, scale))

	bbox = (1.31, .88)
	if legendfile != '': # isolation of the legend
		bbox = (2, 2)

	legend = fig.legend(bbox_to_anchor=bbox)
	if legendfile != '':
		if legendfile != 'x':
			exportLegend(legend, legendfile)
		legend.remove()

	if not show:
		fig.savefig(output, format='pdf', bbox_inches='tight')
	return plt


# script
plts = []

for dataset in ['dj38', 'qa194']:
	plt = figSeq(u"", u"method", 45,
			"plots/rt_graspels_"+dataset+"_24_20_20_seq.pdf", [
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_hw_seq_v', 'hw_seq'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_sk_seq', 'sk_seq'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_hw_par_v', 'hw_par'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_sk_par_firstlevel', 'sk_firstlevel'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_sk_par_staticpool', 'sk_staticpool'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_sk_par_dynamicpool', 'sk_dynamicpool'],
				['data_graspels/seq/rt_seq_'+dataset+'_24_20_20_sk_par_thread', 'sk_thread'],
				],
			scale=.8,
			error=True
			)
	plts.append(plt)


for dataset in ['dj38', 'qa194']:
	plt = figCores(u"", u"number of cores", [2, 4, 6, 8, 10, 12, 14, 16, 18],
			"plots/rt_graspels_"+dataset+"_24_20_20_par.pdf", [
				['data_graspels/var_cores/rt_cores_'+dataset+'_24_20_20_hw_par_v', 'hw_par'],
				['data_graspels/var_cores/rt_cores_'+dataset+'_24_20_20_sk_par_firstlevel', 'sk_firstlevel'],
				['data_graspels/var_cores/rt_cores_'+dataset+'_24_20_20_sk_par_staticpool', 'sk_staticpool'],
				['data_graspels/var_cores/rt_cores_'+dataset+'_24_20_20_sk_par_dynamicpool', 'sk_dynamicpool'],
				['data_graspels/var_cores/rt_cores_'+dataset+'_24_20_20_sk_par_thread', 'sk_thread'],
				],
			scale=.8,
			error=False
			)
	plts.append(plt)


legendfile = 'plots/rt_graspels_qa194_var_grasp_par_legend.pdf'
for grasp_n in range(4, 21, 4):
	plt = figCores(u"", u"number of cores", [2, 4, 6, 8, 10, 12, 14, 16, 18],
			"plots/rt_graspels_qa194_v"+str(grasp_n)+"_20_20_par.pdf", [
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_hw_par_v', 'hw_par'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_firstlevel', 'sk_firstlevel'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_staticpool', 'sk_staticpool'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_dynamicpool', 'sk_dynamicpool'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_thread', 'sk_thread'],
				],
			scale=.48,
			ycor=-.16,
			legendfile=legendfile,
			error=False
			)
	plts.append(plt)
	legendfile = 'x'


#  legendfile = 'plots/rt_graspels_qa194_var_els_iter_max_par_legend.pdf'
#  for els_iter_max in [1, 2, 4, 8, 12, 16, 20, 30, 40, 50]:
	#  plt = figCores(u"", u"number of cores", [2, 4, 6, 8, 10, 12, 14, 16, 18],
			#  "plots/rt_graspels_qa194_4_v"+str(els_iter_max)+"_20_par.pdf", [
				#  ['data_graspels/var_els/rt_cores_qa194_4_'+str(els_iter_max)+'_20_hw_par_v', 'hw_par'],
				#  ['data_graspels/var_els/rt_cores_qa194_4_'+str(els_iter_max)+'_20_sk_par_firstlevel', 'sk_firstlevel'],
				#  ['data_graspels/var_els/rt_cores_qa194_4_'+str(els_iter_max)+'_20_sk_par_staticpool', 'sk_staticpool'],
				#  ['data_graspels/var_els/rt_cores_qa194_4_'+str(els_iter_max)+'_20_sk_par_dynamicpool', 'sk_dynamicpool'],
				#  ['data_graspels/var_els/rt_cores_qa194_4_'+str(els_iter_max)+'_20_sk_par_thread', 'sk_thread'],
				#  ],
			#  scale=.48,
			#  ycor=-.13,
			#  legendfile=legendfile,
			#  error=True
			#  )
	#  plts.append(plt)
	#  legendfile = 'x'


for grasp_n in range(4, 21, 4):
	values = loadData('data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_hw_par_v')
	basetime = np.mean(values[1])
	plt = figCoresSpeedup(u"", u"number of cores", [2, 4, 6, 8, 10, 12, 14, 16, 18],
			"plots/rt_graspels_qa194_"+str(grasp_n)+"_20_20_speedup.pdf", basetime, [
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_hw_par_v', 'hw_par'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_firstlevel', 'sk_firstlevel'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_staticpool', 'sk_staticpool'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_dynamicpool', 'sk_dynamicpool'],
				['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_thread', 'sk_thread'],
				],
			scale=.8
			)
	plts.append(plt)


#  for cores in [1, 2, 4, 6, 8, 10, 12, 14, 16, 18]:
#  #  for cores in [16]:
	#  basetimes = []
	#  for grasp_n in range(4, 21, 4):
		#  values = loadData('data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_hw_par_v')
		#  basetimes.append(np.mean(values[1]))
	#  values = loadData('data_graspels/var_cores/rt_cores_qa194_24_20_20_hw_par_v')
	#  basetimes.append(np.mean(values[1]))
#  
	#  hw_par = ['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_hw_par_v' for grasp_n in range(4, 21, 4)]
	#  hw_par.append('data_graspels/var_cores/rt_cores_qa194_24_20_20_hw_par_v')
	#  firstlevel = ['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_firstlevel' for grasp_n in range(4, 21, 4)]
	#  firstlevel.append('data_graspels/var_cores/rt_cores_qa194_24_20_20_sk_par_firstlevel')
	#  staticpool = ['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_staticpool' for grasp_n in range(4, 21, 4)]
	#  staticpool.append('data_graspels/var_cores/rt_cores_qa194_24_20_20_sk_par_staticpool')
	#  dynamicpool = ['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_dynamicpool' for grasp_n in range(4, 21, 4)]
	#  dynamicpool.append('data_graspels/var_cores/rt_cores_qa194_24_20_20_sk_par_dynamicpool')
	#  thread = ['data_graspels/var_grasp/rt_cores_qa194_'+str(grasp_n)+'_20_20_sk_par_thread' for grasp_n in range(4, 21, 4)]
	#  thread.append('data_graspels/var_cores/rt_cores_qa194_24_20_20_sk_par_thread')
#  
	#  plt = figSizeSpeedup(u"", u"$N$", [4, 8, 12, 16, 20, 24],
			#  "plots/rt_graspels_qa194_all_20_20_speedup_"+str(cores)+".pdf", basetimes, cores, [
				#  [hw_par, 'hw_par'],
				#  [firstlevel, 'sk_firstlevel'],
				#  [staticpool, 'sk_staticpool'],
				#  [dynamicpool, 'sk_dynamicpool'],
				#  [thread, 'sk_thread'],
				#  ],
			#  scale=.7
			#  )
	#  plts.append(plt)


if show:
	for plt in plts:
		plt.show()
