--- Build strict file-reference rules for MSBuild project files
-- @module formats.vcxproj.references

local vcxproj_references = {}

--- Return whether one MSBuild attribute directly names one local file
-- @param reference table parsed file reference
-- @return boolean accepted
local function is_local_file(reference)
	local path = reference.path

	return (path:find("/", 1, true) ~= nil
			or path:find("\\", 1, true) ~= nil
			or path:match("[^/\\]+%.[^/\\]+$") ~= nil)
		and not path:find("$(", 1, true)
		and not path:find("%(", 1, true)
		and not path:find("@(", 1, true)
		and not path:find("*", 1, true)
		and not path:find("?", 1, true)
		and not path:find(";", 1, true)
		and (path:match("^%a:[/\\]") ~= nil or path:match("^%a[%w+%.%-]*:") == nil)
end

--- Return direct file-valued MSBuild attributes
-- @return table rules
function vcxproj_references.new()
	local rules = {}

	for _, attribute in ipairs({ "Include", "Update", "Remove", "Project" }) do
		-- Pattern breakdown: attribute frontiers reject longer names such as 'AdditionalIncludeDirectories'
		local prefix = "%f[%w_:]" .. attribute .. "%f[^%w_:%-]%s*=%s*"
		for _, quote in ipairs({ "\"", "'" }) do
			rules[#rules + 1] = {
				prefix = prefix,
				open = quote,
				close = quote,
				validate = is_local_file,
			}
		end
	end

	return rules
end

return vcxproj_references
