require('strict')
-- local genitive = require('Module:Genitive')._genitive
local contLang = mw.language.getContentLanguage  
local cmodule = {}
local conf = require 'Module:External links/conf'(contLang:getCode)
local hasdatafromwikidata = false
local hasdatafromlocal = false
local haswikidatalink = true -- we assume it's connected  
local p = {}  
local function getLabel(entity, use_genitive, pagetitle)
local label = (pagetitle and pagetitle ~= '') and pagetitle or nil
if not label and not entity then
label = mw.title.getCurrentTitle.text
elseif not label then
label = mw.wikibase.label(entity.id) or mw.title.getCurrentTitle.text
end
-- return use_genitive and genitive(label, 'sitt') or label
return use_genitive and label .. "'s" or label
end  
-- @todo cleanup, this is in production, use the console
local function dump(obj)
return "<pre>" .. mw.dumpObject(obj) .. "</pre>"
end  
local function stringFormatter( datavalue )
if datavalue == nil or datavalue['type'] ~= 'string' then
return nil
end
return datavalue.value
end  
local pval = {}
pval.P1793 = { -- format as a regular expression
types = {
snaktype = 'value',
datatype = 'string',
},
}  
pval.P407 = { -- language of work or name
types = {
snaktype = 'value',
datatype = 'wikibase-item',
datavalue = {
type = 'wikibase-entityid',
}
},
}  
pval.P364 = { -- original language of work
types = {
snaktype = 'value',
datatype = 'wikibase-item',
datavalue = {
type = 'wikibase-entityid',
}
},
}  
pval.P218 = { -- ISO 639-1 language
types = {
snaktype = 'value',
datatype = 'external-id',
datavalue = {
type = 'string',
}
},
}  
pval.P305 = { -- IETF language tag
types = {
snaktype = 'value',
datatype = 'external-id',
datavalue = {
type = 'string',
}
},
}  
pval.P582 = { -- end time
types = {
snaktype = 'value',
datatype = 'time',
datavalue = {
type = 'string',
}
},
}  
-- This is a really makeshift crappy converter, but it'll do some basic
-- conversion from PCRE to Lua-style patterns (note that this only work
-- in very few cases)
local function regexConverter( regex )
local output = regex
output = string.gsub(output, "\\d{2}", "%%d%%d")
output = string.gsub(output, "\\d{3}", "%%d%%d%%d")
output = string.gsub(output, "\\d{4}", "%%d%%d%%d%%d")
output = string.gsub(output, "\\d{5}", "%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{6}", "%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{7}", "%%d%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{8}", "%%d%%d%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d", "%%d")  
return output
end  
local function getFormatterUrl( prop, value )
local head = ""
local tail = ""
local entity = mw.wikibase.getEntity(prop)
-- to avoid deep tests
if not entity or not entity.claims then
return head
end
-- get the claims for this entity
local statements = entity.claims['P1630'] -- formatter URL
-- to avoid deep tests
if not statements then
return head
end
local formatters = {}
-- let's go through the claims
for _, claim in ipairs( statements ) do
-- to avoid deep tests
if not claim then
claim = {}
end
local valid = claim['type'] == 'statement'
and claim['rank'] ~= 'deprecated'
if valid then
local mainsnak = claim.mainsnak or {}
local preferred = claim['rank'] == 'preferred'
-- get any qualifiers for this claim (we are interested in P1793 for
-- indication of which claim is correct)
local qualifiers = claim.qualifiers or {}
-- now let's check the qualifier we are interested in
local qualid = 'P1793' -- format as a regular expression
-- if the claim has this qualifier
if qualifiers[qualid] then
-- it's here, let's check it out!
local items = {}
-- traverse all snaks in this qualifier
for _, qualsnak in ipairs( qualifiers[qualid] ) do
if qualsnak and pval[qualid] then
--mw.log("qualsnak = " .. dump(qualsnak))
-- check if the snak is of the correct snaktype and datatype
local valid = qualsnak.snaktype == pval[qualid].types.snaktype
and qualsnak.datatype == pval[qualid].types.datatype
if valid then
-- we'll have to convert the regex to Lua-style
local regex = regexConverter(qualsnak.datavalue.value)
local test = string.match( value, '^'..regex..'$' )
if test then
-- it matched, this is correct and overrides any other.
if preferred then
head = mainsnak.datavalue.value
else
tail = mainsnak.datavalue.value
end
end
end
end
end
else
-- we don't have any qualifier, is it preferred?
if (head == * and preferred) or (tail == * and not preferred) then
-- if we don't have any other, use this one
if preferred and head == '' then
head = mainsnak.datavalue.value
elseif not preferred and tail == '' then
tail = mainsnak.datavalue.value
end
end
end
end
end
return head ~= '' and head or tail  
end  
local function getLanguageData(prop, qid)
local head = {}
local tail = {}
-- mw.log("getLanguageData, prop="..dump(prop).." qid="..dump(qid))
-- get the entity we are checking
local entity = mw.wikibase.getEntityObject(qid)
-- to avoid deep tests
if not entity then
return nil
end
if not entity.claims then
return {}
end
-- get the claims for this entity
local statements = entity.claims[prop]
-- to avoid deep tests
if not statements then
return {}
end
-- mw.log("getLanguageData going through claims="..dump(statements))
-- let's go through the claims
for _, claim in ipairs( statements ) do
-- to avoid deep tests
if not claim then
claim = {}
end
local valid = claim['type'] == 'statement'
and claim['rank'] ~= 'deprecated'
if valid then
local mainsnak = claim.mainsnak or {}
local preferred = claim['rank'] == 'preferred'
-- verify the item is what we expect
local valid = mainsnak.snaktype == pval[prop].types.snaktype
and mainsnak.datatype == pval[prop].types.datatype
and mainsnak.datavalue.type == pval[prop].types.datavalue.type
if valid then
-- mw.log("getLanguageData claim is valid="..dump(claim))
-- if this is the correct P-value, dive into it and get P218 (ISO 639-1)
if mainsnak.property == 'P364' then -- original language of work
if preferred then
head[#head+1] = table.concat(getLanguageData('P218', 'Q'..mainsnak.datavalue.value['numeric-id']), conf:a('mod-filter-separator'))
else
tail[#tail+1] = table.concat(getLanguageData('P218', 'Q'..mainsnak.datavalue.value['numeric-id']), conf:a('mod-filter-separator'))
end
elseif mainsnak.property == 'P218' or mainsnak.property == 'P305' then -- ISO 639-1 code or IETF language tag
if preferred then
head[#head+1] = stringFormatter(mainsnak.datavalue)
else
tail[#tail+1] = stringFormatter(mainsnak.datavalue)
end
end
end
end
end
-- mw.log("getLanguageData returning head="..dump(head).." tail="..dump(tail))
return #head>0 and head or tail
end  
local langqvalorder = {'P407','P364'}
local otherqvalorder = {'P582'}  
local function getValuesFromWikidata(props)
local head = {}
local tail = {}
-- mw.log("getValuesFromWikidata, props="..dump(props))
-- get the entity we are checking
local entity = mw.wikibase.getEntityObject
-- to avoid deep tests
if not entity then
--mw.log("getValuesFromWikidata no entity")
return nil
end
if not entity.claims or not props or not props.prop or props.prop == '' then
--mw.log("getValuesFromWikidata no claims or no props")
return {}
end
-- get the claims for this entity
local statements = entity.claims[props.prop]
-- to avoid deep tests
if not statements then
return {}
end
-- let's go through the claims
for _, claim in ipairs( statements ) do
-- to avoid deep tests
if not claim then
claim = {}
end
local valid = claim['type'] == 'statement'
and claim['rank'] ~= 'deprecated'
if valid then
-- mw.log("getValuesFromWikidata valid claim="..dump(claim))
local mainsnak = claim.mainsnak or {}
local preferred = claim['rank'] == 'preferred'
-- get the content of the claim (the identifier)
local langcode = props.langcode
local checklangcode = nil
if props.langcode and props.langcode ~= '' then
checklangcode = string.find(langcode, "([pP]%d+)")
end
if checklangcode and checklangcode ~= "" then
-- this is a P-value for language-code, so we'll check qualifiers for languagedata
-- first get any qualifiers