Module:Monthly Challenge year summary/month

--[=[
Module description
]=]

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

local DATA_PATTERN = 'Module:Monthly Challenge year summary/data/%s'

local DAILY_DATA = 'Module:Monthly Challenge daily stats/data/%d-%02d'
local MONTH_DATA = 'Module:Monthly_Challenge/data/%d-%02d'

local function make_list( lines )
	local out = ''
	for i, v in pairs( lines ) do
		out = out .. '*' .. v .. '\n'
	end
	return out	
end

function metatable_len( mt )
	local c = 0
	for i, _ in pairs( mt ) do
		c = c + 1
	end
	return c
end

function get_month_data( year, month )

	local ddata_module = string.format( DAILY_DATA, year, month )
	local ddata = mw.loadData( ddata_module )
	
	local mdata_module = string.format( MONTH_DATA, year, month )
	local mdata = mw.loadData( mdata_module )

	if not mdata or not ddata then
		error( string.format( 'No data found for month %d-%d', year, month ) )
	end
	
	return mdata, ddata
end

function get_days_in_month(month, year)
	local days_in_month = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }   
	local d = days_in_month[month]
   
	-- check for leap year
	if (month == 2) then
    	if (math.mod(year,4) == 0) then
    		if (math.mod(year,100) == 0) then
    			if (math.mod(year,400) == 0) then
        			d = 29
    			end
    		else
    			d = 29
    		end
    	end
	 end
  return d  
end

--[=[
Return a wikitext UL of month data
]=]
function p.month_data(frame)
	local args = getArgs(frame)
	local year = tonumber( args.year )
	local month = tonumber( args.month )
	local mdata, ddata = get_month_data( year, month )

	local s = ddata.days[0]
	local e = ddata.days[metatable_len(ddata.days) - 1]

	-- Default to zero if insufficient data exists to generate stats
	local validated = 0
	local proofread = 0
	local wo_text   = 0

	-- Don't try to calculate if we don't even have any data
	if s ~= nil and e ~= nil then
		-- Only calculate if there is data for at least one day this month
		-- This will still break if the s or e tables do not contain q1, q3,
		-- or q4 members but guarding each leaf node makes for messy code.
		if metatable_len(ddata.days) >= 1 then
			validated = e.q4 - s.q4
			proofread = e.q3 - s.q3
			wo_text   = e.q0 - s.q0
		end
	end
	local processed = wo_text + proofread + 2 * validated
	
	local now = os.date( '*t' )
	local isCurrent = now.year == year and now.month == month
	local target = mdata.target
	
	local success = false
	if isCurrent then
		-- adjust the target pro-rata
		target = target * ( now.day / get_days_in_month( month, year ) )
	end
	success = processed >= target
	
	local successClass = "ws-mc-year-summary-" .. ( success and 'success' or 'failure' )
	if isCurrent then
		successClass = successClass .. " " .. "ws-mc-year-summary-current"
	end
	
	local proc_span = mw.html.create( 'span' )
		:addClass( successClass )
		
	if isCurrent then
		proc_span
			:wikitext('~')
			:attr( 'title', 'This challlenge is still in progress, this number is an estimate.')
	end
	
	proc_span:wikitext( processed )

	local percent_span = mw.html.create( 'span' )
		:addClass( successClass )
		
	if isCurrent then
		percent_span
			:wikitext('~')
			:attr( 'title', 'This challlenge is still in progress, this number is an estimate.')
	end
	
	percent_span:wikitext( string.format( '%d%%', 100 * processed / mdata.target ) )
		
	local lines = {}
	
	table.insert( lines, string.format( 'Pages processed: %s', tostring( proc_span ) ) )
	table.insert( lines, string.format( '*(%s of %d)', tostring( percent_span ), mdata.target ) )
	table.insert( lines, string.format( 'Pages proofread: %d', proofread + validated ) )
	table.insert( lines, string.format( 'Pages validated: %d', validated ) )
	-- table.insert( lines, string.format( 'Works proofread: %d', metatable_len( m_data.works.proofread ) ) )
	-- table.insert( lines, string.format( 'Works validated: %d', metatable_len( m_data.works.validated ) ) )

	return make_list( lines )
end

return p