Documentation for this module may be created at Module:Sandbox/Premeditated/Test/doc

local p = {}
require("strict")

-- Wrapper for pcall which returns nil on failure.
local function quickPcall(func)
	local success, result = pcall(func)
	if success then
		return result
	end
end

-- Count words by ','
local function countpattern(x) 
	local _, count = x:gsub(", ","") 
	return count 
end

-- Get the rank of statement from table
local function getRank(prop)
	local rank = prop.rank
	if rank == 'preferred' then
		return 1
	elseif rank == 'normal' then
		return 0
	elseif rank == 'deprecated' then
		return -1
	else
		return 0 -- No rank or undefined rank is treated as "normal".
	end
end

-- Get the Q-id from the site or arg.
local function getId(id)
    local artikkel
    if not mw.wikibase then
        return ''
    end
    if id then
    	artikkel = mw.wikibase.getEntity(id)
    else
    	artikkel = mw.wikibase.getEntity()
    end
    if not artikkel then
    	return ''
    end
    return artikkel
end

-- Gets all values and add a dot (".") to it.
p.file_extension = function(frame)
 	local exts = {}
	
    local artikkel = getId(frame.args[1])
    if artikkel == "" then
    	return ""
    end
	local fileExten = quickPcall(function ()
		return artikkel:getBestStatements('P1195')
	 end)
	
	if fileExten == nil then
		return ""
	end
	
	for i, ext in ipairs(fileExten) do
	    exts[#exts+1] = ("." .. ext.mainsnak.datavalue.value)
	end
	return mw.text.nowiki(table.concat(exts, ', '))
end

local function formatEntityId(entityId,i)
    local label
    local link = mw.wikibase.sitelink( entityId )
	if i == 1 then
    	label = mw.wikibase.label( entityId )
    	label = label:gsub("^%l", string.upper)
    else
    	label = mw.wikibase.label( entityId )
    end
    if link then
        if label then
            return '[[' .. link .. '|' .. label .. ']]'
        else
            return '[[' .. link .. ']]'
        end
    elseif label then
        return label --TODO what if no links and label + fallback language?
    else
        return ''
    end
end

-- Gets all values and if multip. add [[multi paradigm]]: ...
p.paradigm = function(frame)
	local pid = frame.args.pid --Property-ID to find best match
	local notAllowed = frame.args.notallowed -- Q-value that is not allowed
	local qId = frame.args.qid -- Q-value that is linked to in [[qId|..]
	local collapsedName = frame.args.name -- In collapsed mode name. Like 9 versjoner [vis] or 9 muligheter [vis]
	local multiName = frame.args.multiname -- The name of qId [[qId|multiName]]
	
 	local paradigms = {}
	
    local artikkel = getId(frame.args[1])
    if artikkel == "" then
    	return ""
    end
	local paradigm = quickPcall(function ()
		return artikkel:getBestStatements(pid)
	end)
	
	if paradigm == nil then
		return ""
	end
	local count = 0
	for i, paradig in ipairs(paradigm) do
		if paradig.mainsnak.datavalue.value.id ~= notAllowed then --multi-paradigm programming
			count = count + 1
	    	paradigms[#paradigms+1] = formatEntityId(paradig.mainsnak.datavalue.value.id,count)
	    end
	end

	if paradigms[2] then
		local values = table.concat(paradigms, ', ')
		local multi = '[[' .. mw.wikibase.sitelink(qId) .. '|' .. multiName .. ']]' .. ': '
		if count >= 5 then
			return string.format([[<div class="mw-collapsible mw-collapsed"><div class="sentrert">%s </div> <div class="mw-collapsible-content">%s</div></div>]], 
			count .. ' ' .. collapsedName ,multi .. values)
    	else
    		return multi .. values
    	end
	elseif paradigms[1] then
    	return paradigms[1]
    elseif paradigm[1] then
    	return '[[' .. mw.wikibase.sitelink(qId) .. '|' .. multiName .. ']]'
	end
end


-- Filter on rank and qqid. Then return with "," between statements.
local function findBestProperty(entity, pid, qqid, ppid)
    local props = {}
    local propsAlt = {}

    local prop = quickPcall(function ()
	return entity['claims'][pid]
    end)

    if not prop then
        return ''
    end
	
    for i, pro in ipairs(prop) do
        local rank = getRank(pro)
        if rank == 1 and pro.qualifiers and pro.qualifiers[ppid] and pro.qualifiers[ppid][1].datavalue.value.id == qqid  then
            	props[#props+1] = pro.mainsnak.datavalue.value
        elseif rank == 0 and pro.qualifiers and pro.qualifiers[ppid] and pro.qualifiers[ppid][1].datavalue.value.id == qqid then
        		propsAlt[#propsAlt+1] = pro.mainsnak.datavalue.value
    	end
    end
	if props[1] then 
		return quickPcall(function () 
			return table.concat(props, ', ') 
			end) 
	elseif propsAlt[1] then 
		return quickPcall(function () 
			return table.concat(propsAlt, ', ') 
			end)
	else
		return ''
	end
end

-- Find the version that you are looking for. Adds it to a collapsed class if over 5.
p.version = function(frame)
    local artikkel = getId(frame.args[1]) -- Args[1] is the Q-id (alt)
    local pid = frame.args.pid -- Property (Pxx) under Q-value (Qxxxx)
    local qQid = frame.args.qqid -- Secound Q-id
    local pPid = frame.args.ppid -- Secound P-id (Property)
    local alle = frame.args.alle -- if 'ja' and if findBestProperty() return nil, get all statements
	
    local priVersions = quickPcall(function () 
			return findBestProperty(artikkel,pid,qQid,pPid)
			end)
    if priVersions == '' and alle == 'ja' then
		local temp = artikkel:formatPropertyValues( pid, mw.wikibase.entity.claimRanks )
		priVersions = temp['value']
    end
    if countpattern(priVersions) > 5 then
		return string.format([[<div class="mw-collapsible mw-collapsed"><div class="sentrert">%s versjoner</div> <div class="mw-collapsible-content">%s</div></div>]], 
		countpattern(priVersions), priVersions)
    else
		return mw.text.nowiki(priVersions)
    end
end

return p