--[=[
	Mounts Blend objects into an existing instance.

	:::tip
	Normally specifying ClassName as a property breaks mounting, since you
	can't write to ClassName. However, if you specify ClassName here, it will only
	listen to changes on children with that class name.
	:::

	If multiple instances are named the same thing, then this will
	bind to both.

	:::tip
	This explicitly listens for any children underneath the mounted
	instance with the name passed in here. This is fine for small amounts
	of instances, like in most Gui hierarchies. However, it will be way less
	performance friendly for large class hierarchies.
	:::

	```lua
	maid:GiveTask(Blend.mount(frame, {
		Size = UDim2.new(0.5, 0, 0.5, 0);

		Blend.Find "MyUIScaleName" {
			Scale = 2;
		};
	}))
	```

	@param name string
	@return function
]=]

function Blend.Find(name)
	assert(type(name) == "string", "Bad name")

	return function(props)
		assert(type(props) == "table", "Bad props")

		local mountProps = props
		local className
		if props.ClassName then
			className = props.ClassName
			mountProps = table.clone(props)
			mountProps.ClassName = nil
		else
			className = "Instance"
		end

		return function(parent)
			return RxInstanceUtils.observeChildrenOfNameBrio(parent, className, name):Pipe({
				Rx.flatMap(function(brio)
					if brio:IsDead() then
						return
					end

					local maid = brio:ToMaid()
					local instance = brio:GetValue()
					maid:GiveTask(Blend.mount(instance, mountProps))

					-- Dead after mounting? Clean up...
					-- Probably caused by name change.
					if brio:IsDead() then
						maid:DoCleaning()
					end

					-- Avoid emitting anything else so we don't get cleaned up
					return Rx.EMPTY
				end);
			})
		end
	end
end
