--- Build strict file-reference rules for Java source files
-- @module formats.java.references

local java_references = {}

local import_prefix = "^%s*import%s+"
local static_import_prefix = "^%s*import%s+static%s+"

--- Return whether one dotted Java name ends at the import semicolon
-- @param reference table parsed import reference
-- @param line_text string complete source line
-- @return boolean accepted
local function is_import(reference, line_text)
	if line_text:sub(reference.col2):match("^%s*;") == nil then
		return false
	end

	for part in reference.path:gmatch("[^%.]+") do
		if not part:match("^[%a_$][%w_$]*$") then
			return false
		end
	end

	return reference.path:find("..", 1, true) == nil
end

--- Convert one imported Java type into its source filename
-- @param reference table parsed import reference
-- @return table candidates
local function type_candidates(reference)
	return { reference.path:gsub("%.", PATHSEP) .. ".java" }
end

--- Convert one static member import into its declaring type filename
-- @param reference table parsed static import reference
-- @return table candidates
local function static_type_candidates(reference)
	local type_name = reference.path:match("^(.*)%.[^%.]+$")

	return type_name and { type_name:gsub("%.", PATHSEP) .. ".java" } or {}
end

--- Return direct Java type and static-member imports
-- @return table rules
function java_references.new()
	return {
		{
			prefix = static_import_prefix,
			chars = "[%w_%.$]",
			validate = is_import,
			candidates = static_type_candidates
		},
		{
			prefix = import_prefix,
			chars = "[%w_%.$]",
			validate = is_import,
			candidates = type_candidates
		},
	}
end

return java_references
