Documentation for this module may be created at Module:Ifexist/doc

-- Upstream: [[:zh:Module:Ifexist]]
local p = {}

local function makeTitle(title, callFn)
	if type(title) == type({}) and type(title.fullText) == type('') then
		return title
	elseif type(title) == type('') then
		local success, titleObj = pcall(mw.title.new, title)
		if success and titleObj then
			return titleObj
		end
		return false
	end
	error(string.format(
		'bad argument #1 to \'%s\' (%s expected, got %s)',
		callFn,
		'string or mw.title object',
		type(title)
	))
end

local function wrapCacheAbleExistsFunc(callFn, callback)
	local cache = {}
	return function (title, ...)
		local titleObj = makeTitle(title, callFn)
		if not titleObj or titleObj.interwiki ~= '' then
			return false
		end
		local cacheValue = cache[titleObj.fullText]
		if cacheValue == nil then
			cacheValue = callback(titleObj, ...)
			cache[titleObj.fullText] = cacheValue
		end
		return cacheValue
	end
end

local function wrapIfExists(fn)
	return function (title, thenVal, elseVal)
		return fn(title) and thenVal or elseVal
	end
end

p._luaExists = wrapCacheAbleExistsFunc('_luaExists', function (titleObj)
	return titleObj.exists and true or false
end)

p._luaIfExists = wrapIfExists(p._luaExists)

p._luaFileExists = wrapCacheAbleExistsFunc('_luaFileExists', function (titleObj)
	return (titleObj.namespace == 6 or titleObj.namespace == -2) and titleObj.file.exists and true or false
end)

p._luaFileIfExists = wrapIfExists(p._luaFileExists)

local existsPlaceholder = '__EXISTS__'
local missingPlaceholder = '__MISSING__'
p._pfExists = wrapCacheAbleExistsFunc('_pfExists', function (titleObj)
	return mw.getCurrentFrame():callParserFunction('#ifexist', { titleObj.fullText, existsPlaceholder, missingPlaceholder }) == existsPlaceholder
end)

p._pfIfExists = wrapIfExists(p._pfExists)

p._pfFileExists = wrapCacheAbleExistsFunc('_pfFileExists', function (titleObj)
	if titleObj.namespace == 6 then
		titleObj = mw.title.makeTitle(-2, titleObj.text)
	end
	return titleObj.namespace == -2 and p._pfExists(titleObj) or false
end)

p._pfFileIfExists = wrapIfExists(p._pfFileExists)

function p._detectLangConvDiff(title)
	local titleObj = makeTitle(title, '_detectLangConvDiff')
	if titleObj and titleObj.interwiki == '' then
		local pfExists = p._pfExists(titleObj)
		if pfExists then
			return not p._luaExists(titleObj)
		end
	end
	return false
end

-- //// //// --

local yesno

local function tidyValNoChange(value)
	return value
end

local function tidyValTrim(value)
	return mw.text.trim(value)
end

function p.main(frame)
	if type(yesno) ~= type(tonumber) then
		yesno = require('Module:Yesno')
	end
	local args = frame.args
	local tidyValue = yesno(args.noTrim) and tidyValNoChange or tidyValTrim
	local title = args.title or args[1]
	if not title then
		error('[[Module:Ifexist]]: Missing title.')
	end
	local thenVal = tidyValue(args['then'] or args[2] or title)
	local elseVal = tidyValue(args['else'] or args[3] or '')
	return p._luaIfExists(title, thenVal, elseVal)
end

return p