มอดูล:Sports table/argcheck

local a = {}
local categories = {
	ignored_parameters = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาโดยไม่สนใจพารามิเตอร์',
	missing_results = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาแต่ยังขาดผลการแข่งขัน',
	missing_teams = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาที่ไม่มีทีม',
	orphaned_match_notes = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาพร้อมบันทึกการแข่งขันที่กำพร้า',
	orphaned_names = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาที่มีชื่อกำพร้า',
	orphaned_notes = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาพร้อมหมายเหตุกำพร้า',
	orphaned_results = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาพร้อมผลการแข่งขันที่กำพร้า',
	possible_incorrect_winpoints = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาที่อาจมีแต้มจากการชนะที่ไม่ถูกต้อง',
	possibly_ignored_parameters = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาซึ่งอาจมีพารามิเตอร์ที่ไม่ถูกสนใจ',
	unknown_parameters = 'หมวดหมู่:หน้าที่ใช้ตารางกีฬาโดยไม่ทราบพารามิเตอร์'
}
local good_args = {
	'away_goals_header' = 1,
	'bonus_header' = 1,
	'class_rules' = 1,
	'draw_header' = 1,
	'drawpoints' = 1,
	'float' = 1,
	'for_against_style' = 1,
	'GB_team' = 1,
	'goalpoints' = 1,
	'group_header' = 1,
	'hide_footer' = 1,
	'hide_for_against_columns' = 1,
	'hide_played' = 1,
	'hide_results' = 1,
	'highest_pos' = 1,
	'legs' = 1,
	'loss_before_draw' = 1,
	'loss_before_tie' = 1,
	'losspoints' = 1,
	'lowest_pos' = 1,
	'matches_style' = 1,
	'matches_text' = 1,
	'match_col_width' = 1,
	'note_header_res' = 1,
	'only_pld_pts' = 1,
	'only_totals' = 1,
	'only_fa_totals' = 1,
	'pct_style' = 1,
	'pld_header' = 1,
	'postitle' = 1,
	'perc_first' = 1,
	'pts_first' = 1,
	'ranking_style' = 1,
	'res_col_header' = 1,
	'result_prefix' = 1,
	'rwpoints' = 1,
	'rw_header' = 1,
	'section' = 1,
	'short_style' = 1,
	'show_GB' = 1,
	'show_away_goals' = 1,
	'show_bonus_points' = 1,
	'show_class_rules' = 1,
	'show_draw' = 1,
	'show_groups' = 1,
	'show_limit' = 1,
	'show_matches' = 1,
	'show_positions' = 1,
	'show_rw' = 1,
	'show_status' = 1,
	'show_totals' = 1,
	'solid_cell' = 1,
	'sortable_table' = 1,
	'source' = 1,
	'start_date' = 1,
	'stack_footer' = 1,
	'status_order' = 1,
	'status_pos' = 1,
	'style' = 1,
	'table_header' = 1,
	'table_header_source' = 1,
	'team_header' = 1,
	'team_order' = 1,
	'team_order_start' = 1,
	'teamwidth' = 1,
	'title' = 1,
	'title_source' = 1,
	'transcludesection' = 1,
	'update' = 1,
	'use_against_percentage' = 1,
	'use_goal_average' = 1,
	'use_goal_diff' = 1,
	'use_goal_percentage' = 1,
	'use_goal_ratio' = 1,
	'use_goals_scored' = 1,
	'use_point_percentage' = 1,
	'use_goals_per_match' = 1,
	'use_points_per_match' = 1,
	'use_tie' = 1,
	'winpoints' = 1,
}
local good_args_HA = {
	'ha_side' = 1,
	'hdrawpoints' = 1,
	'adrawpoints' = 1,
	'hlosspoints' = 1,
	'alosspoints' = 1,
	'hwinpoints' = 1,
	'awinpoints' = 1
}
local good_args_PKOT = {
	'showOTloss' = 1,
	'showOTwin' = 1,
	'showPKloss' = 1,
	'showSOloss' = 1,
	'showPKwin' = 1,
	'showSOwin' = 1,
	'show_tiebr' = 1,
	'PKlosspoints' = 1,
	'SOlosspoints' = 1,
	'OTlosspoints' = 1,
	'PKwinpoints' = 1,
	'SOwinpoints' = 1,
	'OTwinpoints' = 1,
	'PKloss_after_loss' = 1,
	'SOloss_after_loss' = 1,
	'OTloss_after_loss' = 1,
	'tiebr_header' = 1,
}
local good_args_BDT = {
	'drawpoints' = 0,
	'game_for_against_style' = 1,
	'point_for_against_style' = 1
}
local good_args_VB = {
	'winpoints' = 0,
	'losspoints' = 0,
	'drawpoints' = 0,
	'bwinpoints' = 1,
	'blosspoints' = 1,
	'swinpoints' = 1,
	'slosspoints' = 1,
	'win3points' = 1,
	'loss3points' = 1,
	'win4points' = 1,
	'loss4points' = 1,
	'win5points' = 1,
	'loss5points' = 1,
	'show_sets' = 1,
	'show_setpoints' = 1,
	'setpoints_before_sets' = 1,
	'best_of' = 1
}
local ignored_args = {
	'date' = 1,
	'ptsfirst' = 1
}
local col_names = {
	'adjust_points' = 1,
	'away_goals' = 1,
	'draw' = 1,
	'loss' = 1,
	'gf' = 1,
	'ga' = 1,
	'group' = 1,
	'pf' = 1,
	'pa' = 1,
	'matches' = 1,
	'pos' = 1,
	'rw' = 1,
	'short' = 1,
	'startpoints' = 1,
	'status' = 1,
	'win' = 1,
}
local col_names_HA = {
	'draw' = 0,
	'loss' = 0,
	'gf' = 0,
	'ga' = 0,
	'pf' = 0,
	'pa' = 0,
	'rw' = 0,
	'hdraw' = 1,
	'adraw' = 1,
	'hloss' = 1,
	'aloss' = 1,
	'hwin' = 1,
	'awin' = 1,
	'hga' = 1,
	'aga' = 1,
	'hgf' = 1,
	'agf' = 1,
	'hpa' = 1,
	'apa' = 1,
	'hpf' = 1,
	'apf' = 1,
}
local col_names_PKOT = {
	'PKloss' = 1,
	'SOloss' = 1,
	'OTloss' = 1,
	'PKwin' = 1,
	'SOwin' = 1,
	'OTwin' = 1,
	'tiebr' = 1
}
local col_names_BDT = {
	'win' = 1,
	'loss' = 1,
	'mf' = 1,
	'ma' = 1,
	'gf' = 1,
	'ga' = 1,
	'pf' = 1,
	'pa' = 1
}
local col_names_VB = {
	'win' = 0,
	'loss' = 0,
	'draw' = 0,
	'bwin' = 1,
	'swin' = 1,
	'bloss' = 1,
	'sloss' = 1,
	'sw' = 1,
	'sl' = 1,
	'spw' = 1,
	'spl' = 1,
	'win3s' = 1,
	'loss3s' = 1,
	'win4s' = 1,
	'loss4s' = 1,
	'win5s' = 1,
	'loss5s' = 1,
}
local tracked_styles = {
	'football' = 'WDL',
	'WDL' = 'WDL',
	'WL' = 'WDL',
	'WDLHA' = 'HA',
	'WDL OT' = 'PKOT',
	'WLHA' = 'HA',
	'WL OT' = 'PKOT',
	'WL PK' = 'PKOT',
	'WL OTL tiebreak' = 'PKOT',
	'Volleyball' = 'VB',
	'Badminton team' = 'BDT'
}
local warn = {}
local track = {}
local function get_tracking_category(category, value)
	return  .. value .. 
end
local function validate_table_values(args, category, bad_char, is_track)
	for _, v in ipairs(args) do
		v = mw.ustring.gsub(v, bad_char, '?')
		if v ==  then
			v = ' '
		end
		if is_track then
			table.insert(track, get_tracking_category(category, v))
		else
			table.insert(warn, get_tracking_category(category, v))
		end
	end
end
function a.check(targs, pargs)
	local teams = {}
	local missing_teams = {}
	local results = {}
	local missing_results = {}
	local orphaned_match_notes = {}
	local orphaned_results = {}
	local orphaned_names = {}
	local orphaned_notes = {}
	local ignored = {}
	local possibly_ignored = {}
	local unknown = {}
	
	local mstyle = mw.ustring.gsub(targs'style' or , '%s_%s_*', ' ')
	mstyle = tracked_stylesmstyle
	
	if mstyle == nil then
		return warn, track
	end
	
	if mstyle == 'HA' then
		for k, v in pairs(good_args_HA) do
			good_argsk = v ~= 0 and v or nil
		end
		for k, v in pairs(col_names_HA) do
			col_namesk = v ~= 0 and v or nil
		end
		if targs'only_fa_totals' then
			col_names'pf' = 1
			col_names'gf' = 1
			col_names'pa' = 1
			col_names'ga' = 1
		end
	end
	
	if mstyle == 'PKOT' then
		for k, v in pairs(good_args_PKOT) do
			good_argsk = v ~= 0 and v or nil
		end
		for k, v in pairs(col_names_PKOT) do
			col_namesk = v ~= 0 and v or nil
		end
	end
	
	if mstyle == 'BDT' then
		for k, v in pairs(good_args_BDT) do
			good_argsk = v ~= 0 and v or nil
		end
		for k, v in pairs(col_names_BDT) do
			col_namesk = v ~= 0 and v or nil
		end
	end
	
	if mstyle == 'VB' then
		for k, v in pairs(good_args_VB) do
			good_argsk = v ~= 0 and v or nil
		end
		for k, v in pairs(col_names_VB) do
			col_namesk = v ~= 0 and v or nil
		end
	end
	
	-- Alternative syntax for team list
	if targs'team_order' and targs'team_order' ~=  then
		local tlist = mw.text.split(targs'team_order', '%s*;,%s*')
		for k, tname in ipairs(tlist) do
			if tname ~=  then
				targs'team' .. k = tname
			end
		end
	end
	
	-- Limited tracking if we are only showing part of the table
	if targs'showteam' then
		local top_pos = tonumber(targs'highest_pos') or 1
		local bottom_pos = tonumber(targs'lowest_pos') or 0
		local N = top_pos - 1
		while targs'team' .. N + 1 ~= nil and (bottom_pos  1) then
						for _, hth_loc in ipairs(hth_local_table) do
							multiref = multiref * (targs'hth_' .. hth_loc and 1 or 0)
						end
					else
						multiref = 0
					end
					if multiref > 0 then
						for _, hth_loc in ipairs(hth_local_table) do
							targs'hth_' .. hth_loc = 
						end
					elseif targs'hth_' .. targs'hth_' .. v then
						targs'hth_' .. targs'hth_' .. v = 
					end
					targs'hth_' .. v = 
				end
			elseif k:find('^result%d%d*$') or k:find('^.*_result%d%d*$') then
				local pre = mw.ustring.gsub(k, '^(.*)result%d%d*$', '%1')
				resultsv = 1
				targsk = 
				if targspre .. 'col_' .. v or targspre .. 'text_' .. v or targspre .. 'note_res_' .. v then
					-- Great!
					if targspre .. 'col_' .. v then
						targspre .. 'col_' .. v = 
					end
					if targspre .. 'text_' .. v then
						targspre .. 'text_' .. v = 
					end
					if targspre .. 'note_res_' .. v then
						local multiref = 1
						local note_res_local_table = mw.text.split(targspre .. 'note_res_' .. v, '%s*,%s*')
						if (#note_res_local_table > 1) then
							for _, note_res_loc in ipairs(note_res_local_table) do
								multiref = multiref * (targspre .. 'note_res_' .. note_res_loc and 1 or 0)
							end
						else
							multiref = 0
						end
						if multiref > 0 then
							for _, note_res_loc in ipairs(note_res_local_table) do
								targspre .. 'note_res_' .. note_res_loc = 
							end
						elseif targspre .. 'note_res_' .. targspre .. 'note_res_' ..  v then
							targspre .. 'note_res_' ..  targspre .. 'note_res_' ..  v = 
						end
						targspre .. 'note_res_' .. v = 
					end
					if targspre .. 'res_col_header' then
						targspre .. 'res_col_header' = 
					end
				else
					table.insert(missing_results, v)
				end
			elseif k:find('^match%d*_.*_.*_note$') then
				local m = mw.ustring.gsub(k, '^(match%d*_.*_.*)_note$', '%1')
				targsk = 
				if targsm then
					if targs'note_' .. v then
						targs'note_' .. v = 
					end
					-- Great!
				else
					table.insert(orphaned_match_notes, m)
				end
			end
		end
	end
	local possible_missing_winpoints = 0
	for k,v in pairs(targs) do
		if v and v ~=  then
			local found_arg = 0
			if type(k) == 'string' then
				if k:find('^adjust_points_') then
					local p = mw.ustring.gsub(k, '^adjust_points_', )
					if (tonumber(v) or 0) ~= 0 then
						local pdiff = (tonumber(targs'win_' .. p or 0) or 0) + tonumber(v)
						if pdiff == 0 then
							possible_missing_winpoints = possible_missing_winpoints + 1
						else
							possible_missing_winpoints = possible_missing_winpoints - 1
						end
					end
				end
				if found_arg == 0 and (good_argsk or k:find('^split%d%d*$')) then
					-- Great!
					found_arg = 1
				end
				if found_arg == 0 and k == 'showteam' then
					-- Great!
					found_arg = 1
					if teamsv ~= 1 then
						table.insert(missing_teams, v)
					end
				end
				if found_arg == 0 and (ignored_argsk or k:find('^att_')) then
					found_arg = 1
					table.insert(ignored, k)
				end
				if found_arg == 0 and k:find('^A-Za-z3-5*_.*$') then
					local p = mw.ustring.gsub(k, '^(A-Za-z3-5*)_.*$', '%1')
					if col_namesp then
						-- Great!
						found_arg = 1
					end
				end
				if found_arg == 0 and k:find('^A-Za-z*_A-Za-z*_.*$') then
					local p = mw.ustring.gsub(k, '^(A-Za-z*_A-Za-z*)_.*$', '%1')
					if col_namesp then
						-- Great!
						found_arg = 1
					end
				end
				if found_arg == 0 and k:find('^match%d*_.*_.*$') then
					local t1 = mw.ustring.gsub(k, '^match%d*_(.*)_(.*)$', '%1')
					local t2 = mw.ustring.gsub(k, '^match%d*_(.*)_(.*)$', '%2')
					found_arg = 1
					if teamst1 == nil or teamst2 == nil then
						if teamst1 == nil then
							table.insert(missing_teams, t1)
						end
						if teamst2 == nil then
							table.insert(missing_teams, t2)
						end
					end
				end
				if found_arg == 0 and k:find('^result_.*_.*$') then
					local t1 = mw.ustring.gsub(k, '^result%d*_(.*)_(.*)$', '%1')
					local t2 = mw.ustring.gsub(k, '^result%d*_(.*)_(.*)$', '%2')
					found_arg = 1
					if teamst1 == nil or teamst2 == nil then
						if teamst1 == nil then
							table.insert(missing_teams, t1)
						end
						if teamst2 == nil then
							table.insert(missing_teams, t2)
						end
					end
				end
				if found_arg == 0 and (k:find('^name_') or k:find('^short_')) then
					found_arg = 1
					table.insert(orphaned_names, k)
				end
				if found_arg == 0 and (k:find('^note_') or k:find('^hth_')) then
					found_arg = 1
					if (k == 'hth_ABC' and v == 'H2H note') then
						table.insert(warn, get_tracking_category(categories.ignored_parameters , 'hth_ABC'))
					elseif (k == 'note_ABC' and v == 'Team note') then
						table.insert(warn, get_tracking_category(categories.ignored_parameters , 'note_ABC'))
					elseif (k == 'note_res_AAA' and v == 'Result note') then
						table.insert(warn, get_tracking_category(categories.ignored_parameters , 'note_res_AAA'))
					else
						table.insert(orphaned_notes, k)
					end
				end
				if found_arg == 0 and (k:find('^col_') or k:find('^text_')) then
					found_arg = 1
					table.insert(orphaned_results, k)
				end
			end
			if found_arg == 0 then
				if pargsk and pargsk ~=  then
					if tonumber(k) then
						k = k .. ' = ' .. v
					end
					table.insert(possibly_ignored, k)
				else
					if tonumber(k) then
						k = k .. ' = ' .. v
					end
					table.insert(unknown, k)
				end
			end
		end
	end
	local bad_char = '^A-Za-z0-9_%(%)%- '
	validate_table_values(unknown, categories.unknown_parameters, bad_char, false)
	validate_table_values(missing_teams, categories.missing_teams, bad_char, false)
	validate_table_values(missing_results, categories.missing_results, bad_char, false)
	validate_table_values(orphaned_results, categories.orphaned_results, bad_char, false)
	validate_table_values(orphaned_names, categories.orphaned_names, '^A-Za-z0-9_ ', false)
	validate_table_values(orphaned_notes, categories.orphaned_notes, bad_char, false)
	validate_table_values(orphaned_match_notes, categories.orphaned_match_notes, bad_char, false)
	validate_table_values(ignored, categories.ignored_parameters, bad_char, false)
	validate_table_values(possibly_ignored, categories.possibly_ignored_parameters, bad_char, true)
	if possible_missing_winpoints > 1 then
		table.insert(track, get_tracking_category(categories.possible_incorrect_winpoints, possible_missing_winpoints))
	end
	
	return warn, track
end
return a