#!/usr/bin/python3

import argparse, json, math, sys, time
import multiprocessing
from PIL import Image
import numpy as np

class Timed:
	def __init__(self, text):
		print(text, end='', flush=True)

	def pretty(self, durr):
		seconds = int(durr)
		days, seconds = divmod(seconds, 86400)
		hours, seconds = divmod(seconds, 3600)
		minutes, seconds = divmod(seconds, 60)
		if days > 0:
			return '%dd%dh%dm%ds' % (days, hours, minutes, seconds)
		elif hours > 0:
			return '%dh%dm%ds' % (hours, minutes, seconds)
		elif minutes > 0:
			return '%dm%ds' % (minutes, seconds)
		else:
			return '%ds' % (seconds,)

	def __enter__(self):
		self.start = time.time()
		return self

	def __exit__(self, *args):
		self.end = time.time()
		print(self.pretty(self.end - self.start))



parser = argparse.ArgumentParser()
parser.add_argument('--infile', type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument('--outfile', type=str, default='out.png')

args = parser.parse_args()

pool = multiprocessing.Pool()

with Timed("Loading json..."):
	obj = json.load(args.infile)

min_tsc = int(obj['min-tsc'])
max_tsc = int(obj['max-tsc'])

def tsc_to_s(tsc):
	return float(tsc - min_tsc)  / 2500000000.0

max_sec = tsc_to_s(max_tsc)
print([min_tsc, max_tsc, max_sec])

min_cpu = int(obj['min-cpu'])
max_cpu = int(obj['max-cpu'])
cnt_cpu = max_cpu - min_cpu + 1
nbins = math.ceil(max_sec * 10)

class Bar:
	def __init__(self):
		pass

with Timed("Creating bins..."):
	bins = []
	for _ in range(0, int(nbins)):
		bar = Bar()
		bins.append([bar, *[*([0] * cnt_cpu), bar] * cnt_cpu])
		# bins.append([0] * cnt_cpu)

	bins = np.array(bins)



def flatten(val):
	secs = tsc_to_s(val[1])
	ratio = secs / max_sec
	b = int(ratio * (nbins - 1))
	## from/to
	from_ = val[2] - min_cpu
	to_   = val[3] - min_cpu
	idx = int(1 + ((cnt_cpu + 1) * to_) + from_)
	return [b, idx, 1]
	## val per cpu
	# cnt = val[2]
	# idx = val[3] - min_cpu
	# # idx = from_
	# return [b, idx, cnt]


with Timed("Compressing data..."):
	compress = map(flatten, obj['values'])

highest  = 1
with Timed("Grouping data..."):
	for x in compress:
		bins[x[0]][x[1]] += x[2]
		highest = max(highest, bins[x[0]][x[1]])

print(highest)
# highest  = 10000000000

with Timed("Normalizing data..."):
	def normalize(v):
		if type(v) is Bar:
			return np.uint32(0xff008000)
		v = v * 255 / float(highest)
		if v > 256:
			v = 255
		u8 = np.uint8(v)
		u32 = np.uint32(u8)

		return (0xff << 24) | (u32 << 16) | (u32 << 8) | (u32 << 0)
	normalizef = np.vectorize(normalize, [np.uint32])

	bins = normalizef(bins)

print(bins.shape)
with Timed("Saving image..."):
	im = Image.fromarray(bins, mode='RGBA')
	im.show()
	im.save(args.outfile)