Aller au contenu

Module:Episode/MultiSeries

De Stargate Wiki Sémantique
Version datée du 1 juin 2026 à 20:56 par LIMAFOX76 (discussion | contributions)
(diff) ← Version précédente | Version actuelle (diff) | Version suivante → (diff)
Documentation icon Documentation module[créer]
-- Module:Episode/MultiSeries
-- Fusionne toutes les séries et saisons (SG-1, SGA, SGU, Films…)
-- Fournit : get(id), get_by_alias(alias), resolve_alias(alias)
-- + Détection automatique des doublons
-- + Cache interne pour éviter le signal 24

------------------------------------------------------------
-- CACHE : si déjà chargé, on renvoie la version en mémoire
------------------------------------------------------------
local cached = package.loaded["Module:Episode/MultiSeries"]
if type(cached) == "table" then
    return cached
end

------------------------------------------------------------
-- Dépendances
------------------------------------------------------------
local utils = require("Module:Episode/Shared/Utils")

------------------------------------------------------------
-- Structure principale
------------------------------------------------------------
local Multi = {
    episodes = {},   -- id → table épisode
    aliases  = {},   -- alias normalisé → id
    loaded   = {},   -- modules chargés
    duplicates = nil -- rapport de doublons
}

------------------------------------------------------------
-- Liste des modules index de séries
-- (tu ajoutes ici SG1, SGA, SGU, Films, etc.)
------------------------------------------------------------
local SERIES_INDEX = {
    "Module:Episode/SG1/Index",
    "Module:Episode/SGA/Index",
    "Module:Episode/SGU/Index",
    "Module:Episode/Films/Index",
}

------------------------------------------------------------
-- Charge un module de saison et fusionne son contenu
------------------------------------------------------------
local function load_season_module(path)
    local ok, mod = pcall(require, path)
    if not ok or type(mod) ~= "table" then
        return false
    end

    for key, value in pairs(mod) do

        ------------------------------------------------------------
        -- Cas 1 : entrée d’épisode (table avec .id)
        ------------------------------------------------------------
        if type(value) == "table" and value.id then
            Multi.episodes[value.id] = value

            -- Ajout des alias déclarés dans l’épisode
            if type(value.aliases) == "table" then
                for _, alias in ipairs(value.aliases) do
                    local norm = utils.normalize_alias(alias)
                    if norm then
                        Multi.aliases[norm] = value.id
                    end
                end
            end

        ------------------------------------------------------------
        -- Cas 2 : alias → id (clé = alias, valeur = id)
        ------------------------------------------------------------
        elseif type(value) == "string" then
            local norm = utils.normalize_alias(key)
            if norm then
                Multi.aliases[norm] = value
            end
        end
    end

    table.insert(Multi.loaded, path)
    return true
end

------------------------------------------------------------
-- Charge un module index de série (liste des saisons)
------------------------------------------------------------
local function load_series_index(path)
    local ok, idx = pcall(require, path)
    if not ok or type(idx) ~= "table" or not idx.list_seasons then
        return
    end

    for _, entry in ipairs(idx.list_seasons()) do
        load_season_module(entry.module)
    end
end

------------------------------------------------------------
-- Détection des doublons (IDs, alias, alias contradictoires)
------------------------------------------------------------
local function detect_duplicates()
    local report = {
        duplicate_ids = {},
        duplicate_aliases = {},
        conflicting_aliases = {},
    }

    -- IDs
    local seen_ids = {}
    for id,_ in pairs(Multi.episodes) do
        if seen_ids[id] then
            table.insert(report.duplicate_ids, id)
        else
            seen_ids[id] = true
        end
    end

    -- Aliases
    local alias_targets = {}
    for alias, id in pairs(Multi.aliases) do
        if alias_targets[alias] and alias_targets[alias] ~= id then
            table.insert(report.conflicting_aliases, {
                alias = alias,
                id1 = alias_targets[alias],
                id2 = id,
            })
        elseif alias_targets[alias] then
            table.insert(report.duplicate_aliases, alias)
        else
            alias_targets[alias] = id
        end
    end

    Multi.duplicates = report
end

------------------------------------------------------------
-- Chargement global (toutes séries + saisons)
------------------------------------------------------------
local function load_all()
    for _, series_path in ipairs(SERIES_INDEX) do
        load_series_index(series_path)
    end
    detect_duplicates()
end

load_all()

------------------------------------------------------------
-- API publique
------------------------------------------------------------

-- Récupère un épisode par ID
function Multi.get(id)
    return Multi.episodes[id]
end

-- Résout un alias → ID
function Multi.resolve_alias(alias)
    if not alias then return nil end
    local norm = utils.normalize_alias(alias)
    return Multi.aliases[norm]
end

-- Récupère un épisode via alias
function Multi.get_by_alias(alias)
    local id = Multi.resolve_alias(alias)
    if id then
        return Multi.get(id)
    end
    return nil
end

------------------------------------------------------------
-- CACHE : on stocke la table Multi pour les appels suivants
------------------------------------------------------------
package.loaded["Module:Episode/MultiSeries"] = Multi
return Multi