-- ============================================================
-- NIS2 Agile - Migration 006: Security & Performance Improvements
-- Data: 2026-02-20
-- Compatibile: MySQL 8.0 (senza CREATE INDEX IF NOT EXISTS)
-- ============================================================

-- Procedura helper: crea indice solo se non esiste
DROP PROCEDURE IF EXISTS create_index_if_not_exists;
DELIMITER //
CREATE PROCEDURE create_index_if_not_exists(
    IN p_table VARCHAR(100),
    IN p_index VARCHAR(100),
    IN p_cols  VARCHAR(500)
)
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.statistics
        WHERE table_schema = DATABASE()
          AND table_name = p_table
          AND index_name = p_index
    ) THEN
        SET @sql = CONCAT('CREATE INDEX `', p_index, '` ON `', p_table, '` (', p_cols, ')');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    END IF;
END //
DELIMITER ;

-- ── 1. Indici performance su incidents ────────────────────────────────────
CALL create_index_if_not_exists('incidents', 'idx_inc_org_status',      'organization_id, status');
CALL create_index_if_not_exists('incidents', 'idx_inc_org_significant',  'organization_id, is_significant');
CALL create_index_if_not_exists('incidents', 'idx_inc_early_warning_due','organization_id, early_warning_due');
CALL create_index_if_not_exists('incidents', 'idx_inc_notification_due', 'organization_id, notification_due');
CALL create_index_if_not_exists('incidents', 'idx_inc_final_report_due', 'organization_id, final_report_due');

-- ── 2. Indici performance su risks ────────────────────────────────────────
CALL create_index_if_not_exists('risks', 'idx_risks_org_status', 'organization_id, status');
CALL create_index_if_not_exists('risks', 'idx_risks_score',      'organization_id, inherent_risk_score');

-- ── 3. Indici performance su audit_logs ───────────────────────────────────
CALL create_index_if_not_exists('audit_logs', 'idx_audit_org_created', 'organization_id, created_at');
CALL create_index_if_not_exists('audit_logs', 'idx_audit_entity',      'entity_type, entity_id');

-- ── 4. Trigger per rendere audit_log immutabile ───────────────────────────
DROP TRIGGER IF EXISTS prevent_audit_log_update;
CREATE TRIGGER prevent_audit_log_update
    BEFORE UPDATE ON audit_logs
    FOR EACH ROW
BEGIN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = 'audit_logs is append-only: UPDATE not permitted';
END;

DROP TRIGGER IF EXISTS prevent_audit_log_delete;
CREATE TRIGGER prevent_audit_log_delete
    BEFORE DELETE ON audit_logs
    FOR EACH ROW
BEGIN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = 'audit_logs is append-only: DELETE not permitted';
END;

-- ── 5. Soft delete su tabelle critiche ────────────────────────────────────
ALTER TABLE risks
    ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;

ALTER TABLE policies
    ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;

ALTER TABLE suppliers
    ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;

-- Indici per le colonne deleted_at
CALL create_index_if_not_exists('risks',    'idx_risks_deleted',    'organization_id, deleted_at');
CALL create_index_if_not_exists('policies', 'idx_policies_deleted',  'organization_id, deleted_at');

-- ── 6. Indice su refresh_tokens ───────────────────────────────────────────
CALL create_index_if_not_exists('refresh_tokens', 'idx_refresh_user_expires', 'user_id, expires_at');

-- ── 7. Pulizia procedura temporanea ───────────────────────────────────────
DROP PROCEDURE IF EXISTS create_index_if_not_exists;

-- ── 8. Verifica ───────────────────────────────────────────────────────────
SELECT 'Migration 006 completed successfully' AS status;
