--[[
	deviation: upstream would print stuff like
		"YourClass name is not a string"
		"YourClass name is an empty string"
	but we omit the "name" in the result since we don't have a name property

	deviation: constructor does not have Function type annotation
]]

function printConstructorName(label: string, constructor, isNot: boolean, isExpected: boolean): string
	-- ROBLOX deviation: omitted handling for tostring() returning non-string as
	-- tostring() always returns string
	local retval = label .. ": "
	if not isNot then
		retval = retval .. ""
	else
		if isExpected then
			retval = retval .. "never "
		else
			retval = retval .. "      "
		end
	end

	if printable(constructor) then
		if #tostring(constructor) == 0 then
			return string.format("%s name is an empty string", label)
		end

		if isExpected then
			retval = retval .. EXPECTED_COLOR(tostring(constructor))
		else
			retval = retval .. RECEIVED_COLOR(tostring(constructor))
		end

		return retval
	else
		local obj = "{ "

		local finished = true
		local started = false

		for key, value in pairs(constructor) do
			-- if we find that we can't print the first few key value pairs
			-- because they aren't nicely printable, we default to
			-- printing the table address with the original retval
			-- the only exception we make is if the key is a __ metamethod

			local kv_pair = nil
			if printable(key) and printable(value) then
				kv_pair = string.format("%s: %s, ", stringify(key), stringify(value))
				-- We don't print key values for metamethods since they don't
				-- provide us with any additional information
			elseif printable(key) and key:find("__") ~= 1 then
				kv_pair = string.format("%s, ", stringify(key))
			end

			-- stop printing key value pairs and append an ellipsis if it exceeds a specific length
			if kv_pair then
				if #obj + #kv_pair > 64 then
					finished = false
					break
				end

				started = true
				obj = obj .. kv_pair
			end
		end

		-- if we were never able to actually create an obj with the
		-- content of the table because the first #kv_pair was too big,
		-- we default to printing the table address with original retval
		if started == false then
			if isExpected then
				return retval .. EXPECTED_COLOR(tostring(constructor))
			end
			return retval .. RECEIVED_COLOR(tostring(constructor))
		end

		if finished then
			-- get rid of trailing comma
			obj = obj:sub(1, -3)
			obj = obj .. " }"
		else
			obj = obj .. "... }"
		end

		if isExpected then
			return retval .. EXPECTED_COLOR(obj)
		end
		return retval .. RECEIVED_COLOR(obj)
	end
end

return {
	printReceivedStringContainExpectedSubstring = printReceivedStringContainExpectedSubstring,
	printReceivedStringContainExpectedResult = printReceivedStringContainExpectedResult,
	printReceivedArrayContainExpectedItem = printReceivedArrayContainExpectedItem,
	printCloseTo = printCloseTo,
	printExpectedConstructorName = printExpectedConstructorName,
	printExpectedConstructorNameNot = printExpectedConstructorNameNot,
	printReceivedConstructorName = printReceivedConstructorName,
	printReceivedConstructorNameNot = printReceivedConstructorNameNot,
}
