local p = {};
require('strict')

local function makelink(link)
	return "<li>[[" .. link.target .. "|" .. link.label .. "]]</li>"
end

local function warning(note)
	return "<li>[[File:Achtung-orange.svg|20px]] "..note.."</li>"
end

local function removeword(link,removelist)
	for i,remove in ipairs(removelist) do
		local char1 = string.sub(remove,1,1)
		local regex = "%f[%w][" .. string.upper(char1) .. string.lower(char1) .. "]" .. string.sub(remove,2) .. "*%f[%W]"
		link = link:gsub(regex,"")
	end
	link = link:gsub("^%s*","") -- strip spaces from start
	link = link:gsub("%s*$","") -- strip spaces from end
	link = link:gsub("^(%l)", mw.ustring.upper) -- capitalise first letter
	return link
end

function p.getlinks(frame)
	local args = frame.args
	local pargs = frame:getParent().args
	local qids = args[1] or pargs[1]
	local sort = true -- sort entries unless sort=no
	if args.sort=='no' or pargs.sort=='no' then
		sort = false
	end
	local redlinks = false -- do not show redlinks unless redlinks=yes
	if args.redlinks=='yes' or pargs.redlinks=='yes' then
		redlinks = true
	end
	local removes = args.remove or pargs.remove or ""
	local removelist = mw.text.split(removes,"%s*,%s*") -- split string into table at commas
	local links = {} -- for constructing the links
	local notes = "" -- for warning messages on the template
	if qids then
		for qid in qids:gmatch("Q%d+") do
			local target = mw.wikibase.sitelink(qid)
			local label = mw.wikibase.getLabel(qid)
			if target then -- sitelink to enwiki exists
				local newlink = {}
				newlink.target = target
				if label then -- make piped link using English label to avoid unnecessary disambiguation terms
					newlink.label = removeword(label,removelist) -- remove common words from label
				else -- there is no label so we are using target as the label
					newlink.label = removeword(target,removelist) -- remove common words from target
				end
				table.insert(links,newlink)
			else -- no sitelink to enwiki exists yet
				if label then -- English label exists
					if redlinks == true then
						if mw.title.new(label).exists then -- [[label]] is already a page linked to a different item
							notes = notes..warning("Cannot show link to [["..label.."]] because it is not linked to [[d:Special:EntityPage/"..qid.."|"..qid.."]]")
						else -- we can create a redlink to [[label]]
							local newlink = {}
							newlink.target = label
							newlink.label = removeword(label,removelist)
							table.insert(links,newlink)
						end
					else -- add warning on template that there is no sitelink
						notes = notes..warning("No sitelink for [["..label.."]]")
					end
				else -- no target and no English label
					if mw.wikibase.entityExists(qid) then
						if redlinks == true then -- add warning on template that no redlink can be generated without label
							notes = notes..warning("Cannot show link to [[d:Special:EntityPage/"..qid.."|"..qid.."]] because no label is defined")
						else -- add warning on template that there is no sitelink available
							notes = notes..warning("No sitelink for [[d:Special:EntityPage/"..qid.."|"..qid.."]]")
						end
					else -- add warning on template that qid is invalid
						notes = notes..warning("Invalid identifier "..qid)
					end
				end
			end
		end
	else
		return "Error: no parameter"
	end
	local links2 = {} -- will contain wikilinks sorted alphabetically
	if #links>0 then
		if sort then
			table.sort(links,function (link1,link2) return link1.label<link2.label end)
		end
		for i,link in ipairs(links) do
			links2[i]=makelink(link)
		end
	end
	local output = '<ul>'..table.concat(links2)..'</ul>'
	if mw.title.getCurrentTitle():inNamespace(10) then
		output = output..notes
	end
	return output
end

function p.convert(frame)
	local args = frame.args
	local pargs = frame:getParent().args
	local input = args[1] or pargs[1]
	if input == nil then
		return nil
	end
	local resolveEntity = require( "Module:ResolveEntityId" )
	local articlelist = mw.text.split(input,"%*%s*")
	local qidlist = {}
	for i,article in ipairs(articlelist) do
		local rawarticle=string.match(article,'%[%[(.+)%|') or string.match(article,'%[%[(.+)%]%]')
		if rawarticle then
			local qid = resolveEntity._id(rawarticle)
	 		if qid then
				qidlist[#qidlist+1] = qid.."<!-- "..rawarticle.." -->"
	 		else
	 			qidlist[#qidlist+1] = "<!-- No QID for "..rawarticle.." -->"
	 		end
		end
	end
	return "{{Article list|"..table.concat(qidlist,", ").."}}"
end

return p