--- Build strict file-reference rules for Go source files
-- @module formats.go.references

local go_references = {}

local embed_first_prefix = "^%s*//go:embed%s+"
local embed_later_prefix = "%s+"
local cgo_include_prefix = "#%s*include%s*"

--- Return whether one embed target is one literal file on an embed line
-- @param reference table parsed embed reference
-- @param line_text string complete source line
-- @return boolean accepted
local function is_embed_file(reference, line_text)
	local path = reference.path
	local next_character = line_text:sub(reference.col2, reference.col2)

	return line_text:match("^%s*//go:embed%s+") ~= nil
		and (reference.rule.open ~= nil or next_character == "" or next_character:match("%s") ~= nil)
		and path:sub(1, 4) ~= "all:"
		and not path:find("*", 1, true)
		and not path:find("?", 1, true)
		and not path:find("[", 1, true)
end

--- Return literal Go embed files and cgo includes
-- @return table rules
function go_references.new()
	return {
		{ prefix = embed_first_prefix, open = "\"", close = "\"", validate = is_embed_file },
		{ prefix = embed_first_prefix, open = "`", close = "`", validate = is_embed_file },
		{ prefix = embed_first_prefix, validate = is_embed_file },
		{ prefix = embed_later_prefix, open = "\"", close = "\"", validate = is_embed_file },
		{ prefix = embed_later_prefix, open = "`", close = "`", validate = is_embed_file },
		{ prefix = embed_later_prefix, validate = is_embed_file },
		{ prefix = cgo_include_prefix, open = "\"", close = "\"" },
		{ prefix = cgo_include_prefix, open = "<", close = ">" },
	}
end

return go_references
