const { collectFontLibrarySyncOperations } = require('../../media/font-library'); const { fetchPlayerRegistrations } = require('#src/data/player-registry'); const TASK = { key: 'initial-font-sync', category: 'fonts' }; function isRecentPlayerRegistration(player, staleSeconds) { const lastSeenAt = player && player.last_seen_at; const lastSeenAtValue = lastSeenAt instanceof Date ? lastSeenAt.getTime() : new Date(lastSeenAt).getTime(); const cutoffTime = Date.now() - Math.max(30, Number(staleSeconds || 60)) * 1000; return Number.isFinite(lastSeenAtValue) && lastSeenAtValue >= cutoffTime; } function normalizePlayerMetadata(player) { const playerIdentifier = String(player && player.identifier || '').trim(); const playerPublicBaseUrl = String(player && player.public_base_url || '').trim(); const playerInternalBaseUrl = String(player && player.internal_base_url || '').trim(); return { playerIdentifier: playerIdentifier || null, playerPublicBaseUrl: playerPublicBaseUrl || null, playerInternalBaseUrl: playerInternalBaseUrl || null, playerLabel: playerIdentifier || playerPublicBaseUrl || playerInternalBaseUrl || null, playerActive: true }; } function registerInitialFontSyncTask(options) { const pool = options && options.pool; const backgroundTaskQueue = options && options.backgroundTaskQueue; const mediaDir = String(options && options.mediaDir || '').trim(); const uploadSyncService = options && options.uploadSyncService; if (!pool || !backgroundTaskQueue || !mediaDir) { throw new Error('registerInitialFontSyncTask requires the initial font sync dependencies.'); } const metadataPromise = uploadSyncService && typeof uploadSyncService.getPlayerTaskMetadata === 'function' ? uploadSyncService.getPlayerTaskMetadata() : Promise.resolve({}); return Promise.resolve(metadataPromise).then(async function () { let players = []; try { players = await fetchPlayerRegistrations(pool); } catch (error) { console.warn('Unable to fetch player registrations for initial font sync:', error); return null; } const livePlayers = Array.isArray(players) ? players.filter(function (player) { return isRecentPlayerRegistration(player, 60); }) : []; if (!livePlayers.length) { return null; } const operations = collectFontLibrarySyncOperations(mediaDir); return Promise.all(livePlayers.map(function (player) { const metadata = normalizePlayerMetadata(player); return backgroundTaskQueue.enqueueTask({ key: TASK.key, title: 'Initial font sync', category: TASK.category, taskType: 'font-sync', metadata: metadata, payload: { mode: 'initial', uploadDir: mediaDir, operations: operations, playerIdentifier: metadata.playerIdentifier, playerPublicBaseUrl: metadata.playerPublicBaseUrl, playerInternalBaseUrl: metadata.playerInternalBaseUrl }, persist: true }); })); }).catch(function (error) { console.warn('Unable to queue initial font sync:', error); }); } module.exports = { registerInitialFontSyncTask };