local w=require(script.Parent.Types)local O=require(script.Parent.Parent.Shared.t)local T=require(script.Parent.Constants)local I={}I.__index=I function I.new(w,O,q,B)assert(B==true or T.RESERVED_SCOPES[q]==nil,("\069\110\116\105\116\121 \115\099\111\112\101 \099\097\110\110\111\116 \098\101 \037\113"):format(q))return setmetatable({rocs=w;instance=O;scope=q},I)end function I.__tostring(w)return("\069\110\116\105\116\121\040\037\115\041"):format(tostring(w.instance))end local q=O.tuple(w.ComponentResolvable,O.optional(O.string))function I._getComponentOpValues(T,w,O,...)assert(q(w,O))return T.instance,T.rocs._aggregates:getStatic(w),O or T.scope,...end function I.addComponent(I,w,O,T)if I.rocs.debug then warn("\065\068\068",I.instance,w,O)end return I.rocs._aggregates:addComponent(I:_getComponentOpValues(w,nil,O or{},T))end function I.removeComponent(O,w)if O.rocs.debug then warn("\082\069\077\079\086\069",O.instance,w)end return O.rocs._aggregates:removeComponent(O:_getComponentOpValues(w))end function I.addBaseComponent(q,w,O,I)return q.rocs._aggregates:addComponent(q:_getComponentOpValues(w,T.SCOPE_BASE,O or{},I))end function I.removeBaseComponent(O,w)return O.rocs._aggregates:removeComponent(O:_getComponentOpValues(w,T.SCOPE_BASE))end function I.getComponent(O,w)return O.rocs._aggregates:get(O:_getComponentOpValues(w))end function I.getAllComponents(w)return w.rocs._aggregates:getAll(w.instance)end function I.removeAllComponents(w)return w.rocs._aggregates:removeAllComponents(w.instance)end function I.getScope(O,w)return O.rocs:getEntity(O.instance,w)end return I
local I = require(script.Parent.Types)
local t = require(script.Parent.Parent.Shared.t)
local Constants = require(script.Parent.Constants)

local Entity = {}
Entity.__index = Entity

function Entity.new(rocs, instance, scope, overrideReserveCheck)
	assert(
		overrideReserveCheck == true or
		Constants.RESERVED_SCOPES[scope] == nil,
		("Entity scope cannot be %q"):format(scope)
	)

	return setmetatable({
		rocs = rocs;
		instance = instance;
		scope = scope;
	}, Entity)
end

function Entity:__tostring()
	return ("Entity(%s)"):format(tostring(self.instance))
end

local getComponentOpValuesCheck = t.tuple(
	I.ComponentResolvable,
	t.optional(t.string)
)
function Entity:_getComponentOpValues(componentResolvable, scope, ...)
	assert(getComponentOpValuesCheck(componentResolvable, scope))
	return
		self.instance,
		self.rocs._aggregates:getStatic(componentResolvable),
		scope or self.scope,
		...
end

function Entity:addComponent(componentResolvable, data, metacomponents)
	if self.rocs.debug then
		warn("ADD", self.instance, componentResolvable, data)
	end
	return self.rocs._aggregates:addComponent(
		self:_getComponentOpValues(componentResolvable, nil, data or {}, metacomponents)
	)
end

function Entity:removeComponent(componentResolvable)
	if self.rocs.debug then
		warn("REMOVE", self.instance, componentResolvable)
	end
	return self.rocs._aggregates:removeComponent(
		self:_getComponentOpValues(componentResolvable)
	)
end

function Entity:addBaseComponent(componentResolvable, data, metacomponents)
	return self.rocs._aggregates:addComponent(
		self:_getComponentOpValues(componentResolvable, Constants.SCOPE_BASE, data or {}, metacomponents)
	)
end

function Entity:removeBaseComponent(componentResolvable)
	return self.rocs._aggregates:removeComponent(
		self:_getComponentOpValues(componentResolvable, Constants.SCOPE_BASE)
	)
end

function Entity:getComponent(componentResolvable)
	return self.rocs._aggregates:get(
		self:_getComponentOpValues(componentResolvable)
	)
end

function Entity:getAllComponents()
	return self.rocs._aggregates:getAll(self.instance)
end

function Entity:removeAllComponents()
	return self.rocs._aggregates:removeAllComponents(self.instance)
end

function Entity:getScope(newScope)
	return self.rocs:getEntity(self.instance, newScope)
end

return Entity
