Documentation for this module may be created at Modul:StringUtils/doc

local p = {}
local arguments = require('Modul:Arguments')
local TableTools = require('Modul:TableTools')

local function makeInvokeFunc(funcName)
	return function (frame)
		local args = arguments.getArgs(frame, { wrappers = 'Format:Ifempty' })
		local firstRet,secondRet = p[funcName](args)
		return firstRet
	end
end

-- Adaugă la începutul unui șir un prefix, dacă nu există deja acolo el sau unul dintre cele listate în ultimul argument
function p._prependIfMissing(args)
	local str = args[1]
	local prefix = args[2]
	local others = {}
	for argK,argV in pairs(args) do
		if argK > 1 then
			table.insert(others, argV)
		end
	end
	if str == nil then return nil end
	if prefix == nil then return str end
	
	for i, eachPrefix in pairs(others) do	
		if mw.ustring.find(str, eachPrefix, 1, true) == 1 then return str end
	end
	return prefix .. str
end
p.prependIfMissing = makeInvokeFunc('_prependIfMissing')

-- Adaugă la sfârșitul unui șir un sufix, dacă nu există deja acolo el sau unul dintre cele listate în ultimul argument
function p._appendIfMissing(args)
	local str = args[1]
	local suffix = args[2]
	local others = {}
	for argK,argV in pairs(args) do
		if argK > 1 then
			table.insert(others, argV)
		end
	end
	if str == nil then return nil end
	if suffix == nil then return str end

	for i, eachSuffix in pairs(others) do
		local suffixStart
		local suffixEnd
		suffixStart, suffixEnd = mw.ustring.find(str, eachSuffix, 1, true) 
		if suffixEnd == mw.ustring.len(str) then return str end
	end
	return str .. suffix
end
p.appendIfMissing = makeInvokeFunc('_appendIfMissing')

function p._emptyToNil(args)
	local str = args[1]
	if str == '' then return nil end
	return str
end
p.emptyToNil = makeInvokeFunc('_emptyToNil')

function p._capitalize(args)
	local str = args[1]
	if str == nil then return nil end
	return mw.ustring.upper(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str,2);
end
p.capitalize = makeInvokeFunc('_capitalize')

function p._removeStart(args)
	local str = args[1]
	if str == nil then return nil end
	local prefix = args[2]
	if prefix == nil then return str end
	if mw.ustring.sub(str, 1, mw.ustring.len(prefix)) == prefix then return mw.ustring.sub(str, mw.ustring.len(prefix) + 1, mw.ustring.len(str)) end
	return str
end
p.removeStart = makeInvokeFunc('_removeStart')

function p._removeEnd(args)
	local str = args[1]
	if str == nil then return nil end
	local suffix = args[2]
	if suffix == nil then return str end
	if mw.ustring.sub(str, -mw.ustring.len(suffix)) == suffix then return mw.ustring.sub(str, 1, -mw.ustring.len(suffix) - 1) end
	return str
end
p.removeEnd = makeInvokeFunc('_removeEnd')

function p.__isEmpty(str)
	return str == nil or (type(str) == 'string' and mw.ustring.len(str) == 0)
end
function p._isEmpty(args)
	local str = args[1]
	return p.__isEmpty(str)
end
p.isEmpty = makeInvokeFunc('_isEmpty')

function p._trim(args)
	local str = args[1]
	if not str then return nil end
	return mw.text.trim(str)
end
p.trim = makeInvokeFunc('_trim')

function p._startsWithAny(args)
	local str = args[1]
	if not str then return false end
	local idx = 2
	while idx <= TableTools.size(args) do
		if args[idx] and mw.ustring.sub(str, 1, mw.ustring.len(args[idx])) == args[idx] then
			return true
		end
		idx = idx + 1
	end
	return false
end
p.startsWithAny = makeInvokeFunc('_startsWithAny')
p._startsWith = p._startsWithAny
p.startsWith = makeInvokeFunc('_startsWith')

function p._endsWithAny(args)
	local str = args[1]
	if not str then return false end
	local idx = 2
	while idx <= TableTools.size(args) do
		if args[idx] and mw.ustring.sub(str, mw.ustring.len(str) - mw.ustring.len(args[idx]) + 1, mw.ustring.len(str)) == args[idx] then
			return true
		end
		idx = idx + 1
	end
	return false
end
p.endsWithAny = makeInvokeFunc('_endsWith')
p._endsWith = p._endsWithAny
p.endsWith = makeInvokeFunc('_endsWith')
	
function p._substringBefore(args)
	local str = args[1]
	if not str then return nil end
	local idx = 2
	local substringEndPos = 1 + mw.ustring.len(str)
	local firstSep = ''
	while idx <= TableTools.size(args) do
		if args[idx] then
			local substringStart = mw.ustring.find(str, args[idx], 1, true)
			if substringStart and substringStart < substringEndPos then
				substringEndPos = substringStart
				firstSep = args[idx]
			end
		end
		idx = idx + 1
	end
	return mw.ustring.sub(str, 1, substringEndPos-1), firstSep
end
p.substringBefore = makeInvokeFunc('_substringBefore')


function p._substringAfter(args)
	local str = args[1]
	if not str then return nil end
	local idx = 2
	local substringStartPos = 1 + mw.ustring.len(str)
	local firstSep = ''
	while args[idx] ~= nil do
		local substringStart = mw.ustring.find(str, args[idx], 1, true)
		if substringStart and substringStart < substringStartPos then
			substringStartPos = substringStart + mw.ustring.len(args[idx])
			firstSep = args[idx]
		end
		idx = idx + 1
	end
	if substringStartPos > mw.ustring.len(str) then return str end
	return mw.ustring.sub(str, substringStartPos), firstSep
end
p.substringAfter = makeInvokeFunc('_substringAfter')

function p._defaultString(args)
	local compressedArgs = TableTools.compressSparseArray(args)

	if #compressedArgs == 0 then return '' end
	return compressedArgs[1]
end
p.defaultString = makeInvokeFunc('_defaultString')

function p._appendToString(args)
	local str = args[1]
	local suffix = args[2]
	if str then
		return tostring(str) .. tostring(suffix or '')
	end
	return ''
end
p.appendToString = makeInvokeFunc('_appendToString')

function p._prependToString(args)
	local str = args[1]
	local prefix = args[2]
	if str then
		return tostring(prefix or '') .. tostring(str)
	end
	return ''
end
p.prependToString = makeInvokeFunc('_prependToString')

function p._encloseString(args)
	return p._prependToString({p._emptyToNil({p._appendToString({args[1], args[3]})}), args[2]})
end
p.encloseString = makeInvokeFunc('_encloseString')

function p._stripNamespace(args)
	s,_ = p._substringAfter({args[1],':'})
	return s
end
p.stripNamespace = makeInvokeFunc('_stripNamespace')

-- Determină dacă o secvență de text conține o legătură spre un articol anume.
function p._findLinkByTitle(args)
	local str = args[1]:gsub('_', ' ')
	local pattern = '%[%[%s*' .. p._trim({(args[2] or ''):gsub('_', ' ')}):gsub('([+*?%-%(%)%%%.])', '%%%1') .. '%s*[%]|]'
	if str then
		return str:find(pattern, 1, false) or 0
	end
	return 0
end
p.findLinkByTitle = makeInvokeFunc('_findLinkByTitle')

function p._firstValue(args)
	local compactedArgs = TableTools.compressSparseArray(args)
	return #compactedArgs > 0 and compactedArgs[1] or ''
end
p.firstValue = makeInvokeFunc('_firstValue')

function p.isNilOrEmpty(argument)
	return argument == nil or argument == {} or mw.text.trim(argument) == ''
end


return p