#![deny(warnings)]
#![allow(dead_code)]
// [TSM.ID].[11031972] — All Rights Reserved. Proprietary & Confidential.
use tracing::debug;

/// Struktur 1 Titik Perubahan Neuromorphic (Spike/Event)
/// Sangat padat memori: X (u16), Y (u16), R (i16), G (i16), B (i16) -> Hanya 10 bytes per piksel yang berubah.
#[derive(Debug, Clone, PartialEq)]
pub struct PulsarEvent {
    pub x: u16,
    pub y: u16,
    pub dr: i16,
    pub dg: i16,
    pub db: i16,
}

/// THE PULSAR CODEC (Phase 43)
/// Neuromorphic Frameless Compression
pub struct PulsarCodec;

impl PulsarCodec {
    /// ENCODER: Menelan dua frame (Frame Lama & Frame Baru)
    /// Membandingkannya secara spatiotemporal dan hanya memuntahkan Koordinat Piksel yang bergerak/berubah.
    pub fn encode_frameless_stream(old_frame: &[u8], new_frame: &[u8], width: u16, height: u16) -> Vec<PulsarEvent> {
        let mut events = Vec::new();
        // Asumsi RGB format (3 bytes per pixel)
        let total_pixels = (width as usize) * (height as usize);
        
        for i in 0..total_pixels {
            let offset = i * 3;
            
            // Cegah out-of-bounds untuk simulasi
            if offset + 2 >= old_frame.len() || offset + 2 >= new_frame.len() {
                break;
            }

            let r_old = old_frame[offset] as i16;
            let g_old = old_frame[offset + 1] as i16;
            let b_old = old_frame[offset + 2] as i16;

            let r_new = new_frame[offset] as i16;
            let g_new = new_frame[offset + 1] as i16;
            let b_new = new_frame[offset + 2] as i16;

            let dr = r_new - r_old;
            let dg = g_new - g_old;
            let db = b_new - b_old;

            // Threshold Sensitivitas (Mengabaikan *noise* kecil dari kamera)
            if dr.abs() > 5 || dg.abs() > 5 || db.abs() > 5 {
                let x = (i % width as usize) as u16;
                let y = (i / width as usize) as u16;
                
                events.push(PulsarEvent { x, y, dr, dg, db });
            }
        }
        
        if events.is_empty() {
            debug!("PULSAR: Tidak ada gerakan. Emitting 0 Bytes.");
        } else {
            debug!("PULSAR: Mengirim {} events piksel perubahan.", events.len());
        }

        events
    }

    /// DECODER: Menerima "Pulsar Events" (Delta pergerakan) dari internet dan langsung
    /// memodifikasi frame yang sudah ada di RAM pengguna tanpa perhitungan matriks DCT.
    pub fn apply_events_to_canvas(canvas: &mut [u8], events: &[PulsarEvent], width: u16) {
        for event in events {
            let offset = ((event.y as usize * width as usize) + event.x as usize) * 3;
            
            if offset + 2 < canvas.len() {
                // Terapkan selisih warna
                let current_r = canvas[offset] as i16;
                let current_g = canvas[offset + 1] as i16;
                let current_b = canvas[offset + 2] as i16;

                // Saturasi clamp agar tidak tembus 255/0
                canvas[offset] = (current_r + event.dr).clamp(0, 255) as u8;
                canvas[offset + 1] = (current_g + event.dg).clamp(0, 255) as u8;
                canvas[offset + 2] = (current_b + event.db).clamp(0, 255) as u8;
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_pulsar_frameless_efficiency() {
        let width = 2;
        let height = 2;
        // Total piksel = 4 (RGB = 12 bytes total per frame)
        // Layar awal: Semua Hitam
        let old_frame: Vec<u8> = vec![0,0,0, 0,0,0, 0,0,0, 0,0,0];
        
        // Layar baru: Hanya 1 piksel di sudut kiri atas (x:0, y:0) yang menyala jadi merah
        let new_frame: Vec<u8> = vec![255,0,0, 0,0,0, 0,0,0, 0,0,0];

        // EKSEKUSI PULSAR ENCODER (Pemusnahan AV1)
        let events = PulsarCodec::encode_frameless_stream(&old_frame, &new_frame, width, height);
        
        // PEMBUKTIAN EFISIENSI MUTLAK
        // Alih-alih mengirim frame utuh, mesin HANYA mengirim 1 event (1 piksel)!
        assert_eq!(events.len(), 1);
        assert_eq!(events[0].dr, 255);
        assert_eq!(events[0].x, 0);
        assert_eq!(events[0].y, 0);

        println!("PULSAR ENCODE BERHASIL: Efisiensi memori hancur! Frame tidak dikirim. Hanya 10 bytes koordinat perubahan yang dikirim.");

        // EKSEKUSI PULSAR DECODER
        let mut client_canvas = old_frame.clone();
        PulsarCodec::apply_events_to_canvas(&mut client_canvas, &events, width);

        // Pastikan kanvas diubah sempurna sesuai new_frame tanpa memproses 3 piksel lainnya
        assert_eq!(client_canvas, new_frame);
        println!("PULSAR DECODE BERHASIL: Kanvas direkonstruksi seketika (Zero-Latency) tanpa perhitungan blok (DCT) CPU!");
    }
}
