--[=[
Module description
]=]

local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs

local function formatLink(target, display)
	if not display then
		display = target
	end
	return '[' .. '[' .. target .. '|' .. display .. ']]'
end

local function commaAndList( l )
	local c = #l
	
	if c == 0 then
		return ''
	end
	
	if c == 1 then
		return l[1]
	end
	
	local out = ''
	for k, v in pairs(l) do
		out = out .. v
		if k ~= c then
			if k ~= c - 1 then
				out = out .. ', '
			else
				out = out .. ' and '
			end
		end
	end
	return out
end

--[=[
Construct a textual list of authors from a table of Creator objects

Returns mw.html tag
]=]
local function renderAuthorLinks( authorList, class )
	
	local links = {}
	for _, creator in pairs( authorList ) do
		
		local linkTarget
		local display = creator.label
		
		-- no WS sitelink? guess the link target and make a red link
		-- todo: category?
		if not creator.wsPage then
			linkTarget = 'Author:' .. creator.label
		else
			linkTarget = creator.wsPage
		end
		
		local innerTag = mw.html.create( 'span' )
			:addClass( 'wst-worklink-creator' )
			:wikitext( formatLink( linkTarget, display ) )

		table.insert( links, tostring( innerTag ) )
	end
	
	local outerTag = mw.html.create( 'span' )
		:addClass( class )
		:wikitext( commaAndList( links ) )
	
	return outerTag
end

function p.renderLink(args)
	
	--mw.logObject(args)
	local out = mw.html.create( 'span' )
		:addClass( 'wst-worklink' )
		
	if args.classes then
		out:addClass( table.concat( args.classes, ' ' ) )
	end
	
	if args.chapter or args.chapterDisplay then

		local chapterPageTitle = args.title .. '/' .. args.chapter
		
		local chapter = formatLink( chapterPageTitle,
			args.chapterDisplay or args.chapter )
		
		out:tag( 'span' )
			:addClass( 'wst-worklink-chapter' )
			:wikitext( '"' .. chapter .. '"' )
			
		out:wikitext(' in ')
	end
	
	local title
	if args.no_link then
		title = args.title or args.display
	else
		title = formatLink( args.title, args.display )
	end
		
	out:tag( 'span' )
		:addClass( 'wst-worklink-title' )
		:wikitext( title )
		
	local comma = false

	if args.authors and #args.authors then
		out:wikitext( ' by ' .. tostring(
			renderAuthorLinks( args.authors, 'wst-worklink-authors' ) )
		)
		comma = true
	end
	
	if args.editors and #args.editors then
		if comma then
			out:wikitext( ',' )
		end
		out:wikitext( ' ed. ' .. tostring(
			renderAuthorLinks( args.editors, 'wst-worklink-editors' ) )
		)
		comma = true
	end
	
	if args.translators and #args.translators then
		if comma then
			out:wikitext( ',' )
		end
		out:wikitext( ' tr. ' .. tostring(
			renderAuthorLinks( args.translators, 'wst-worklink-translators' ) )
		)
		comma = true
	end
	
	if args.illustrators and #args.illustrators then
		if comma then
			out:wikitext( ',' )
		end
		out:wikitext( ' illus. ' .. tostring(
			renderAuthorLinks( args.illustrators, 'wst-worklink-illustrators' ) )
		)
		comma = true
	end
	
	if args.year then
		out:wikitext( ' (' )
		out:tag( 'span' )
			:addClass( 'wst-worklink-date' )
			:wikitext( args.year )
		out:wikitext( ')' )
	end
	
	return out
end

--[=[
Combine all arguments with a given prefix into a table of author links
]=]
local function combineAuthors(args, prefix)
	local l = {}
	local i = 1
	
	while true do
		local argname = prefix
		local dispargname = prefix .. "_display"
		if i > 1 then
			argname = argname .. i
			dispargname = dispargname .. i
		end
		
		-- ran out of arguments
		if not args[argname] then
			break
		end
		
		local target = args[argname]
		
		if string.find( target, 'Portal:', 1, true ) ~= 1 then
			target = 'Author:' .. target
		end
		
		local display = args[dispargname] or args[argname]
		-- strip namespaces
		display = display:gsub( '^%w-:', '' )

		table.insert( l, {
			link = target,
			label = display
		} )
		i = i + 1
	end
	return l
end

--[=[
Function docs
]=]
function p.book_link(frame)
	local args = getArgs(frame)
	
	if args.author then
		args.authors = combineAuthors(args, 'author')
	end
	
	return tostring(p.renderLink(args))
end

return p