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

-- version 20220121 from master @cawiki
local p = {}

local module_data = "Module:Wikidades" -- change to local name if needed

-- year threshold by state, if no specific function, if no P571 (inception) or not convenient inception date
-- previous dates are anachronic referents, 0 = no date, default = 1945
local anachronic_date =
{
	['Q159'] = 1547, -- Russia, Russian SFSR, Russian Empire, Tsardom of Russia
	['Q212'] = 1945, -- Ukraine from II WW
	['Q262'] = 1515, -- Algeria, Ottoman Algeria
	['Q734'] = 1831, -- Guyana and British Guiana
}

---- Fetch from Wikidata, support fuctions for cases by language

function p.fetchAdministrativeEntity(qid, lang)
	local adm_list = require(module_data).getParentValues{
		item = qid,
		property = 'P131', -- located in the administrative territorial entity
		label = 'P31', -- instance of
		formatting = 'label',
		labelformat = 'raw',
		separator = '<adm entity>',
		lang = lang,
		editicon = 'false'
		}
	local adm = {}
	for adm_e in mw.text.gsplit(adm_list or '', '<adm entity>', true) do
		table.insert(adm, mw.text.split(adm_e, ' = '))
	end
	
	return adm
end

function p.getReferencedEntity(qid, entities)
	local adm_statements = mw.wikibase.getAllStatements(qid, 'P131')
	for _, snak in ipairs(adm_statements) do
		local id = snak.mainsnak.datavalue.value.id
		if entities[id] then
			return entities[id]
		end
	end
	return
end

function p.getAdmByID(adm_table, adm_id, loc_label)
	for _, v in ipairs(adm_table) do
		if v[1] == adm_id then
			if v[2] == loc_label then
				return
			else
				return v[2]
			end
		end
	end
	return
end

function p.addReferent(text1, text2, ref_format)
	if text2 == nil or #text2 == 0 then
		return text1
	elseif ref_format == 'brackets' then
		return text1 .. ' (' .. text2 .. ')'
	end
	return text1 .. ', ' .. text2
end

---- Local functions

local function getContextDate(qid)
	local c_date = require(module_data).claim{
		item = qid,
		property = 'P570 or P569 or P2031', -- biographic dates
		formatting = 'Y',
		list = 'false',
		editicon = 'false'
		}
	if not c_date then
		c_date = require(module_data).claim{
		item = qid,
		property = 'P26 or P166 or P1411 or P39 or P551',
		qualifier = 'P580 or P585',
		formatting = 'table',
		rowformat = '$1',
		colformat1 = 'Y',
		list = 'false',
		editicon = 'false'
		}
	end
	if not c_date then return 0 end
	local raw_date = string.match(c_date, "(%d+)") -- remove preffixes or suffixes
	if raw_date ~= c_date then
		raw_date = '0'
	end
	return tonumber(raw_date)
end

local function fetchInception(qid)
	local c_date = require(module_data).claim{
		item = qid,
		property = 'P571',
		formatting = 'Y',
		list = 'false',
		editicon = 'false'
		}
	if not c_date then return end
	local raw_date = string.match(c_date, "(%d+)") -- remove preffixes or suffixes
	if raw_date ~= c_date then
		raw_date = '0'
	end
	return tonumber(raw_date)
end

local function namingLocationByState(qid, label, _date, lang, ref_format)
	local state_date = anachronic_date[qid] or fetchInception(qid) or 1945
	if _date < state_date then
		return label
	end
	local state = require(module_data).getLabel{qid, lang=lang, editicon='false'}
	if mw.ustring.find(state, label, 1, true) or mw.ustring.find(label, state, 1, true) then
		return label
	end
	return p.addReferent(label, state, ref_format)
end

-- on debug console: =p.debug{['args']={'Q385923'}}
function p.debug(frame)
	local id = frame.args[1] or mw.wikibase.getEntityIdForCurrentPage()
	local lang = frame.args.lang
	local loc_label = require(module_data).getLabel{id, lang=lang}
	local context_id = frame.args[2]
	return p.naming(loc_label, lang, id, context_id)
end

-- main function
function p.naming(loc_label, ...)
	local lang = arg[1]
	local loc_id = arg[2]
	local page_id = arg[3]
	
	local module_lang = 'Module:Location/' .. (lang or mw.language.getContentLanguage().code)
	if not pcall(require, module_lang) then
		module_lang = nil
	end
	if module_lang then
		local ret = require(module_lang).namingExceptions(loc_id)
		if ret then
			return loc_label
		end
	end
	
	local context_date, ref_format
	if page_id then
		context_date = getContextDate(page_id)
	else
		context_date = os.date('*t').year
	end
	local state_snak = mw.wikibase.getBestStatements(loc_id, 'P17')
	if #state_snak == 1 and state_snak[1].mainsnak.datavalue then
		-- more than one best statement of state is potencially conflictive,
		-- and skip novalue
		local state_id = state_snak[1].mainsnak.datavalue.value.id
		if module_lang then
			local ret = require(module_lang).namingLocation(state_id, loc_id, loc_label, context_date, p)
			if ret then return ret end
			ref_format = require(module_lang).referentFormat
		end
		return namingLocationByState(state_id, loc_label, context_date, lang, ref_format)
	end
	return loc_label
end

return p