#!/usr/bin/env lua5.1

args = {...}

vfile = assert(args[1], "arg1 missing: .v file")
table.remove(args,1)
assert(#args > 0, "arg missing: at lease one aux file")
data_files = args

source = assert(io.open(vfile), "unable to open "..vfile):read("*a")

function htmlescape(s)
	return (s:gsub("&","&amp;"):gsub("<","&lt;"):gsub(">","&gt;"))
end

colors = {
  '#F08080', '#EEE8AA', '#98FB98'
}

assert(#data_files <= #colors, "only ".. #colors .." data files are supported")

vname = vfile:match("([^/]+.v)$")

print([[
<html>
<head>
<title>]]..vname..[[</title>
<style>]])
for i,k in ipairs(colors) do
  print(
  ".time" .. i .. " {"..
    "background-color: " .. k .. ";"..
    "height: ".. 100 / #data_files .."%;"..
	"top: " .. 100 / #data_files * (i - 1) .. "%;"..
	"z-index: -1; position: absolute; opacity: 50%; }")
end
print([[.code {
  z-index: 0;
  position: relative;
  border-style: solid;
  border-color: transparent;
  border-width: 1px;
}
.code:hover {
  border-color: black;
}
pre {
  display: inline;
}
</style>
</head>
<body>
<h1>Timings for ]]..vname..[[</h1>
<ol>
]])
for i,data_file in ipairs(data_files) do
	print('<li style="background-color: '..colors[i]..'">' .. data_file .. "</li>")
end
print("</ol>")

all_data = {}

for _, data_file in ipairs(data_files) do
  local data = {}
  local last_end = -1
  local lines = 1
  for l in io.lines(data_file) do
	local b,e,t = l:match('^Chars ([%d]+) %- ([%d]+) %S+ ([%d%.]+) secs')
	if b then
		if tonumber(b) > last_end + 1 then
			local text = string.sub(source,last_end+1,b-1)
			if not text:match('^%s+$') then
				local _, n = text:gsub('\n','')
				data[#data+1] = {
					start = last_end+1; stop = b-1; time = 0;
					text = text; lines = lines
				}
				lines = lines + n
				last_end = b
			end
		end
		local text = string.sub(source,last_end+1,e)
		local _, n = text:gsub('\n','')
		local _, eoln = text:match('^[%s\n]*'):gsub('\n','')
		data[#data+1] = {
			start = b; stop = e; time = tonumber(t); text = text;
			lines = lines
		}
		lines = lines + n
		last_end = tonumber(e)
	end
  end
  if last_end + 1 <= string.len(source) then
	local text = string.sub(source,last_end+1,string.len(source))
	data[#data+1] = {
		start = last_end+1; stop = string.len(source); time = 0;
		text = text; lines = lines+1
		}
  end
all_data[#all_data+1] = data
end

max = 0; 
for _, data in ipairs(all_data) do
	for _,d in ipairs(data) do
		max = math.max(max,d.time)
	end
end

data = all_data[1]
for j,d in ipairs(data) do
	print('<div class="code" title="File: '..vname..
		'\nLine: '..d.lines..'\n')
	for k=1,#all_data do
		print('Time'..k..': '..all_data[k][j].time..'s')
	end
	print('">')
	for k=1,#all_data do
		print('<div class="time'..k..'" style="width: '.. 
			all_data[k][j].time * 100 / max ..'%"></div>')
	end
	if d.text == '\n' then
		print('<pre>\n\n</pre>')
	elseif d.text:match('\n$') then
		print('<pre>'..htmlescape(d.text)..'\n</pre>')
	else
		print('<pre>'..htmlescape(d.text)..'</pre>')
	end
	print("</div>")
end

print [[
</body>
</html>
]]

-- vim: set ts=4:

--for i = 1,#data do
--	io.stderr:write(data[i].text)
--end
