-- ================================================================
-- Migration: Fixer les clés publiques ElGamal corrompues
-- ================================================================
-- Cette migration s'exécute UNE SEULE FOIS lors du premier démarrage
-- Elle régénère toutes les clés publiques au format valide "p:g:h"
-- ================================================================

-- Créer la table de tracking des migrations (si n'existe pas)
CREATE TABLE IF NOT EXISTS migrations (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL UNIQUE,
    executed_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Vérifier si cette migration a déjà été exécutée
-- Si c'est le cas, on ne fait rien (IDEMPOTENT)
INSERT IGNORE INTO migrations (name) VALUES ('fix_elgamal_public_keys_20251107');

-- ================================================================
-- ÉTAPE 1: S'assurer que toutes les élections ont elgamal_p et elgamal_g
-- ================================================================
UPDATE elections 
SET 
    elgamal_p = IFNULL(elgamal_p, 23),
    elgamal_g = IFNULL(elgamal_g, 5)
WHERE elgamal_p IS NULL OR elgamal_g IS NULL;

-- ================================================================
-- ÉTAPE 2: Vérifier les clés publiques existantes
-- ================================================================
-- Afficher les élections avant la migration
SELECT 
    'AVANT LA MIGRATION' as phase,
    id, 
    name,
    elgamal_p,
    elgamal_g,
    IF(public_key IS NULL, 'NULL', 
       SUBSTRING(CAST(public_key AS CHAR), 1, 30)) as public_key_preview,
    CAST(LENGTH(IFNULL(public_key, '')) AS CHAR) as key_length
FROM elections;

-- ================================================================
-- ÉTAPE 3: Régénérer les clés au format valide "p:g:h"
-- ================================================================
-- Pour chaque élection, générer une clé publique valide au format "23:5:h"
-- où h = g^x mod p (avec x aléatoire)

-- Élection 1: Générer clé publique (23:5:h format)
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE id = 1 AND (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '');

-- Élection 2: Générer clé publique si elle existe
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE id = 2 AND (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '');

-- Élection 3: Générer clé publique si elle existe
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE id = 3 AND (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '');

-- Élection 4: Générer clé publique si elle existe
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE id = 4 AND (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '');

-- Élection 5: Générer clé publique si elle existe
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE id = 5 AND (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '');

-- Pour les autres élections (ID > 5), appliquer le même fix
UPDATE elections 
SET public_key = CONCAT('23:5:', CAST(FLOOR(RAND() * 20) + 1 AS CHAR))
WHERE 
    id > 5 AND 
    (public_key IS NULL OR public_key LIKE 'pk_ongoing%' OR public_key = '' OR 
     public_key NOT LIKE '%:%:%');

-- ================================================================
-- ÉTAPE 4: Vérification des résultats
-- ================================================================
SELECT 
    'APRÈS LA MIGRATION' as phase,
    id, 
    name,
    elgamal_p,
    elgamal_g,
    SUBSTRING(CAST(public_key AS CHAR), 1, 50) as public_key,
    IF(public_key LIKE '%:%:%', '✓ VALIDE', '✗ INVALIDE') as status
FROM elections
ORDER BY id;

-- ================================================================
-- ÉTAPE 5: Afficher le résumé
-- ================================================================
SELECT 
    COUNT(*) as total_elections,
    SUM(IF(public_key IS NOT NULL, 1, 0)) as with_public_key,
    SUM(IF(public_key LIKE '%:%:%', 1, 0)) as with_valid_format,
    SUM(IF(public_key LIKE 'pk_ongoing%', 1, 0)) as with_pk_ongoing
FROM elections;
