--- Build strict file-reference rules for Sass and SCSS documents
-- @module formats.sass.references

local common = require("core.common")
local sass_references = {}

local use_prefix = "@use%f[^%w_%-]%s*"
local forward_prefix = "@forward%f[^%w_%-]%s*"
local import_prefix = "@import%f[^%w_%-]%s*"
local later_import_prefix = ",%s*"
local import_line_pattern = common.caseless_pattern("^%s*" .. import_prefix)

--- Return whether one target belongs to a supported Sass directive and is local
-- @param reference table parsed file reference
-- @param line_text string complete source line
-- @return boolean accepted
local function is_local_target(reference)
	local path = reference.path

	return path:match("^%a:[/\\]") ~= nil or path:match("^%a[%w+%.%-]*:") == nil
end

--- Return whether one later target belongs to a Sass import line
-- @param reference table parsed file reference
-- @param line_text string complete source line
-- @return boolean accepted
local function is_later_import(reference, line_text)
	return line_text:match(import_line_pattern) ~= nil and is_local_target(reference)
end

--- Return one filename with an underscore added to its basename
-- @param filename string Sass filename
-- @return string partial_filename
local function partial_filename(filename)
	local directory, basename = filename:match("^(.*[/\\])([^/\\]+)$")

	return (directory or "") .. "_" .. (basename or filename)
end

--- Return normal, partial, and index filenames used by Sass resolution
-- @param reference table parsed Sass reference
-- @return table candidates
local function sass_candidates(reference)
	local filename = reference.path
	if filename:match("[^/\\]+%.[^/\\]+$") then
		return { filename, partial_filename(filename) }
	end

	return {
		filename,
		filename .. ".scss",
		filename .. ".sass",
		partial_filename(filename) .. ".scss",
		partial_filename(filename) .. ".sass",
		filename .. PATHSEP .. "_index.scss",
		filename .. PATHSEP .. "_index.sass",
		filename .. PATHSEP .. "index.scss",
		filename .. PATHSEP .. "index.sass",
	}
end

--- Return quoted Sass module and import references
-- @return table rules
function sass_references.new()
	local rules = {}

	for _, prefix in ipairs({ use_prefix, forward_prefix, import_prefix }) do
		for _, quote in ipairs({ "\"", "'" }) do
			rules[#rules + 1] = {
				prefix = prefix,
				open = quote,
				close = quote,
				validate = is_local_target,
				candidates = sass_candidates,
				caseless = true,
			}
		end
	end

	for _, quote in ipairs({ "\"", "'" }) do
		rules[#rules + 1] = {
			prefix = later_import_prefix,
			open = quote,
			close = quote,
			validate = is_later_import,
			candidates = sass_candidates,
		}
	end

	return rules
end

return sass_references
