local a={"\115";"\109\115","\206\188\115";"\110\115"}local function E(E)local C=1 while E<1 do E*=1000.0 C+=1 end return string.format("\037\046\048\049\102",E)..a[C]end return function(a,C,s)local p=string.format("\037\100 \080\097\115\115\101\100\044 \037\100 \083\107\105\112\112\101\100\044 \037\100 \070\097\105\108\101\100",table.unpack(C))local T={" "..(string.rep(" ",#p/2-10).."\226\128\148\226\128\148 \069\122\083\112\101\099 \082\101\115\117\108\116\115 \226\128\148\226\128\148");" "..(p.."\n")}local N=s.useEmojis for a,C in pairs(a)do table.insert(T,"\t"..((N and"\240\159\147\129 "or"")..a))for a,C in pairs(C)do if typeof(C)=="\115\116\114\105\110\103"then table.insert(T,"\t\t"..((N and"\240\159\167\170 "or"\062 ")..a))table.insert(T,"\t\t\t"..((N and"\240\159\155\145 "or"")..C))continue end local s=0 local function p(a)local C={}local T={}local L={}for W,R in pairs(a.results)do local d=R.name local c=N and"\240\159\148\180"or"\091\088\093"local U=C if R.skipped then if R.fixme then c=N and"\240\159\148\167"or"\091\063\093"else c=N and"\240\159\159\161"or"\091-\093"end U=L elseif R.passed then c=N and"\240\159\159\162"or"\091\043\093"U=T end local J=string.rep("\t",a.depth)..("\t\t"..(c..(" "..d)))local I=#string.gsub(J,"\t",string.rep(" ",4))if not N then I+=3 end local V if R.time then V=E(R.time)I+=#V end if I>s then s=I end table.insert(U,{name=J,msg=R.err and" \058\058 "..string.gsub(R.err,"\094\037\115\042\091\037\119\037\046\093-\058\037\100-\058\037\115\042",""),time=V,length=I;subSections=R.nestedTests and p(R.nestedTests)or nil})end return{C,T,L}end local L=p(C)local W=""if C.time then local p=E(C.time)W=" "..(string.rep("\046",((s-#a)-#p)-9)..(" "..p))end table.insert(T,"\t\t"..((N and"\240\159\167\170 "or"\062 ")..(a..W)))local function R(a)for a,E in pairs(a)do for a,E in pairs(E)do local C=E.name if E.msg or E.time then local a if E.time then a=" "..(string.rep("\046",(s-E.length)+4)..(" "..E.time))else a=string.rep(" ",(s-E.length)+5)end C..=a..(E.msg and E.msg or"")end table.insert(T,C)if E.subSections then R(E.subSections)end end end end R(L)end end print("\n",table.concat(T,"\n"),"\n")end
local suffixes = { "s"; "ms"; "μs"; "ns"; }
local function suffixedTime(num)
	local suffix = 1
	while num < 1 do
		num *= 1e3
		suffix += 1
	end

	return string.format("%.01f", num) .. suffixes[suffix]
end

return function(results, counts, config)
	local formattedCounts = string.format(
		"%d Passed, %d Skipped, %d Failed",
		table.unpack(counts)
	)

	local output = {
		" "
			.. string.rep(" ", (#formattedCounts / 2) - 10)
			.. "—— EzSpec Results ——";
		" " .. formattedCounts .. "\n";
	}

	local useEmojis = config.useEmojis

	for dirName, dirResults in pairs(results) do
		table.insert(output, "\t" .. (useEmojis and "📁 " or "") .. dirName)

		for moduleName, moduleTests in pairs(dirResults) do
			if typeof(moduleTests) == "string" then
				table.insert(
					output,
					"\t\t" .. (useEmojis and "🧪 " or "> ") .. moduleName
				)
				table.insert(
					output,
					"\t\t\t" .. (useEmojis and "🛑 " or "") .. moduleTests
				)
				continue
			end

			local longest = 0

			local function tabulateResults(tests)
				local fails = { }
				local passes = { }
				local skips = { }

				for _, testResult in pairs(tests.results) do
					local testName = testResult.name

					local marker = useEmojis and "🔴" or "[X]"
					local section = fails

					if testResult.skipped then
						if testResult.fixme then
							marker = useEmojis and "🔧" or "[?]"
						else
							marker = useEmojis and "🟡" or "[-]"
						end
						section = skips
					elseif testResult.passed then
						marker = useEmojis and "🟢" or "[+]"
						section = passes
					end

					local name = string.rep("\t", tests.depth)
						.. "\t\t"
						.. marker
						.. " "
						.. testName

					local length = #string.gsub(name, "\t", string.rep(" ", 4))

					if not useEmojis then
						length += 3
					end

					local timeStr
					if testResult.time then
						timeStr = suffixedTime(testResult.time)
						length += #timeStr
					end

					if length > longest then
						longest = length
					end

					table.insert(section, {
						name = name;
						msg = testResult.err and " :: " .. string.gsub(
							testResult.err,
							"^%s*[%w%.]-:%d-:%s*", -- Taken from BoatTEST, used to remove traceback from error
							""
						);
						time = timeStr;
						length = length;
						subSections = testResult.nestedTests
								and tabulateResults(
									testResult.nestedTests
								)
							or nil;
					})
				end

				return { fails; passes; skips; }
			end

			local moduleSections = tabulateResults(moduleTests)

			local moduleEnd = ""
			if moduleTests.time then
				local moduleTime = suffixedTime(moduleTests.time)
				moduleEnd = " "
					.. string.rep(".", longest - #moduleName - #moduleTime - 9)
					.. " "
					.. moduleTime
			end

			table.insert(
				output,
				"\t\t"
					.. (useEmojis and "🧪 " or "> ")
					.. moduleName
					.. moduleEnd
			)

			local function insertSections(sections)
				for _, section in pairs(sections) do
					for _, result in pairs(section) do
						local line = result.name
						if result.msg or result.time then
							local join
							if result.time then
								join = " "
									.. string.rep(
										".",
										longest - result.length + 4
									)
									.. " "
									.. result.time
							else
								join = string.rep(
									" ",
									longest - result.length + 5
								)
							end

							line ..= join .. (result.msg and result.msg or "")
						end

						table.insert(output, line)

						if result.subSections then
							insertSections(result.subSections)
						end
					end
				end
			end

			insertSections(moduleSections)
		end
	end

	print("\n", table.concat(output, "\n"), "\n")
end
