Module:GroupedRosterChangesAbstract

local util_args = require('Module:ArgsUtil') local util_cargo = require("Module:CargoUtil") local util_esports = require("Module:EsportsUtil") local util_html = require("Module:HtmlUtil") local util_map = require("Module:MapUtil") local util_news = require("Module:NewsUtil") local util_source = require("Module:SourceUtil") local util_table = require("Module:TableUtil") local util_text = require("Module:TextUtil") local util_title = require("Module:TitleUtil") local util_vars = require("Module:VarsUtil") local i18n = require('Module:i18nUtil')

local m_team = require('Module:Team') local RoleList = require('Module:RoleList')

local lang = mw.getLanguage('en')

local LCS = require('Module:LuaClassSystem').class

local h = {}

local p = LCS.abstract

function p:init(name) self.CHANGES_TO_REMOVE = {} if name then i18n.init(name) end i18n.init('NewsUtil') end

function p:run(args) local changesData = self:makeAndRunQuery(args) self:formatRawDataRows(changesData) local changesByLine = self:getChangesByLine(changesData) self:markUnwantedLinesForDeletion(changesByLine, args) self:removeLinesToDelete(changesByLine) self:formatForOutput(changesByLine) self:storeCargo(changesByLine) return self:makeOutput(changesByLine) end

function p:makeAndRunQuery(args) return util_cargo.queryAndCast(self:getQuery(args)) end

function p:getQuery(args, player) local ret = { tables = self:getTables, join = self:getJoin, fields = self:getFields, where = self:getWhere(args), orderBy = self:getOrderBy, groupBy = self:getGroupBy, types = { IsApproxDate = 'boolean', IsContractRemoval = 'boolean', }	}	util_cargo.logQuery(ret) return ret end

function p:getTables end function p:getJoin end function p:getFields return { 'RC.Date_Sort', 'RC.Player', 'PR._pageName=PlayerLink', 'RC.Team', 'RC.Role', 'RC.Roles', 'RC.RoleModifier', 'RC.Source', 'RC.IsGCD', 'RC.Preload', 'RC.Direction', 'RC.Status', 'RC._pageName=RCPage', 'RC.RosterChangeId', 'RC.Tags__full=Tags', 'News.Date_Display', 'News.Region [region]', 'News.Sentence', 'News._pageName', 'News.NewsId', 'News.IsApproxDate', } end function p:getOrderBy return 'News.Date_Sort ASC, News.N_LineInDate ASC, RC.N_LineInNews ASC' end function p:getWhere end function p:getGroupBy end

function p:formatRawDataRows(changesData) -- ensure stuff is properly separated for start/end -- this way later on we can simply merge the two rows and have a fluid start -> end for _, row in ipairs(changesData) do		self:formatOneRawDataRow(row) end end

function p:formatOneRawDataRow(row) if not row.RCPage then self:formatOneNonRCRow(row) return end row.Key = self:getKey(row) row.Roles = RoleList(row.Roles, { modifier = row.RoleModifier }) row.Date_Sort = lang:formatDate('Y-m-d', row.Date_Sort) row.Date = row.Date_Sort row.RoleArgs = { sub = row.RoleModifier == 'Sub', trainee = row.RoleModifier == 'Trainee' } if not row.Direction then error(('Missing direction: %s'):format(row.NewsId)) end for _, v in ipairs(util_news.ALL_POSSIBLE_CHANGES) do row[v .. (row.Direction or '')] = row[v] end h.copyConstantsToWhen(row, (row.Direction or '')) row.PlayerLink = row.PlayerLink or row.Player row.RosterChangeIds = { row.RosterChangeId } if row.Tags then row.Tags = util_text.split(row.Tags) end end

function p:formatOneNonRCRow(row) end

function p:getKey(row) end

function h.copyConstantsToWhen(row, when) -- TODO: ditch the clone here somehow -- this mw.clone could be a problem!!!!!!!!! -- because of the Region object!!!!!!!!!!!!! local row2 = mw.clone(row) for k, v in pairs(row2) do row[k .. when] = v	end end

function p:getChangesByLine(changesData) local index = {} local changesByLine = {} for _, row in ipairs(changesData) do		self:updatePlayerChangesAndIndex(changesByLine, row, index) end return changesByLine end

function p:updatePlayerChangesAndIndex(changesByLine, row, fullIndex) if not row.RCPage then self:updateAncillaryInformation(changesByLine, row) return end if not self:isOriginalNews(changesByLine, row, fullIndex[row.Key]) then return end self:setEarlierRowNextTeamValues(changesByLine, row) if not self:isAlreadyIndexed(fullIndex[row.Key], row) then self:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex) return end if self:doWeNeedANewLine(changesByLine, row, fullIndex[row.Key]) then self:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex) return end util_vars.log(row.TeamJoin) self:updatePlayerChangesForExistingLine(changesByLine, row, fullIndex[row.Key]) end

function p:updateAncillaryInformation(changesByLine, row) end

function p:isOriginalNews(changesByLine, row, index) end

function p:teamsAreIdentical(row, oldrow, when) end

function p:getOldRowFromIndex(changesByLine, row, info) return changesByLine[info.changeNumber] end

function p:isAlreadyIndexed(index, row) return index end

function p:doWeNeedANewLine(changesByLine, index) end

function p:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex) changesByLine[#changesByLine+1] = h.getNewChangeEntry(row) row.changeIndex = #changesByLine util_table.initTable(fullIndex, row.Key) self:updateIndexNew(changesByLine, row, fullIndex[row.Key]) end

function p:updateIndexNew(changesByLine, row, index) self:updateIndex(changesByLine, row, index) end

function h.getNewChangeEntry(row) -- we earlier split stuff into separate start/end so we should be fine to just use assignment here -- can change this to a clone if we need to reuse data ever return row end

function p:updatePlayerChangesForExistingLine(changesByLine, row, index) local oldIndex = self:getMostRecentLineNumberFromIndex(index) self:updateExistingLineAtOldIndex(changesByLine, row, oldIndex) self:updateIndexExisting(changesByLine, row, index) end

function p:updateIndexExisting(changesByLine, row, index) end

function p:getMostRecentLineNumberFromIndex(index) end

function p:updateIndex(changesByLine, row, index) end

function p:updateExistingLineAtOldIndex(changesByLine, row, oldIndex) self:addNewTeamToExistingLine(changesByLine[oldIndex], row) self:moveExistingLine(changesByLine, oldIndex) end

function p:addNewTeamToExistingLine(line, row) -- we earlier split stuff into separate start/end so we should be fine to just merge now util_table.merge(line, row) line.RoleModifier = row.RoleModifier -- in case it's nil end

function p:moveExistingLine(changesByLine, oldIndex) end

function p:setEarlierRowNextTeamValues(changesByLine, row) end

function p:markUnwantedLinesForDeletion(changesByLine, args) for i, row in ipairs(changesByLine) do		if not self:isLineWanted(row, args) then self.CHANGES_TO_REMOVE[#self.CHANGES_TO_REMOVE+1] = i		end end end

function p:isLineWanted(row, args) return true end

function p:removeLinesToDelete(changesByLine) table.sort(self.CHANGES_TO_REMOVE) for i = #self.CHANGES_TO_REMOVE, 1, -1 do		table.remove(changesByLine, self.CHANGES_TO_REMOVE[i]) end end

function p:formatForOutput(changesByLine) for i, row in ipairs(changesByLine) do		row.index = i		self:formatRowForOutput(row) end end

function p:formatRowForOutput(changesByLine) end

function p:storeCargo(changesByLine) end

function p:makeOutput(changesByLine) end

return p