local s=(require(script.Parent.Parent.topoRuntime)).useCurrentSystem local Q=require(script.Parent.Parent.World)local a=require(script.Parent.Parent.rollingAverage)local i=Q.query local function q(q)Q.query=function(Q,...)if s()==q.debugSystem then local s=os.clock()for s in i(Q,...)do end local U,z=debug.info(2,"\115\108")local u=U..z local N=q._queryDurationSamples local b=N[u]if not b then b={}N[u]=b end local Y={}for s=1,select("\035",...),1 do table.insert(Y,tostring(select(s,...)))end local c=os.clock()-s a.addSample(b,c)local v=a.getAverage(q._queryDurationSamples[U..z])table.insert(q._queries,{averageDuration=v,componentNames=Y})end return i(Q,...)end end local function U()Q.query=i end return{hookWorld=q;unhookWorld=U}
--#selene:allow(empty_loop)
local useCurrentSystem = require(script.Parent.Parent.topoRuntime).useCurrentSystem
local World = require(script.Parent.Parent.World)
local rollingAverage = require(script.Parent.Parent.rollingAverage)

local originalQuery = World.query

local function hookWorld(debugger)
	World.query = function(world, ...)
		if useCurrentSystem() == debugger.debugSystem then
			local start = os.clock()

			-- while this seems like a mistake, it is necessary!
			-- we duplicate the query to avoid draining the original one.
			-- we iterate through so we can calculate the query's budget
			-- see https://github.com/matter-ecs/matter/issues/106
			-- and https://github.com/matter-ecs/matter/pull/107
			for _ in originalQuery(world, ...) do
			end

			local file, line = debug.info(2, "sl")

			local key = file .. line
			local samples = debugger._queryDurationSamples
			local sample = samples[key]
			if not sample then
				sample = {}
				samples[key] = sample
			end

			local componentNames = {}
			for i = 1, select("#", ...) do
				table.insert(componentNames, tostring((select(i, ...))))
			end

			local duration = os.clock() - start
			rollingAverage.addSample(sample, duration)

			local averageDuration = rollingAverage.getAverage(debugger._queryDurationSamples[file .. line])

			table.insert(debugger._queries, {
				averageDuration = averageDuration,
				componentNames = componentNames,
			})
		end

		return originalQuery(world, ...)
	end
end

local function unhookWorld()
	World.query = originalQuery
end

return {
	hookWorld = hookWorld,
	unhookWorld = unhookWorld,
}
