#![deny(warnings)]
// [TSM.ID].[11031972] — All Rights Reserved. Proprietary & Confidential.
use anyhow::Result;
use sha2::{Sha256, Digest};
use tracing::debug;

/// THE ECLIPSE MATRIX (Phase 46)
/// Polymorphic Obfuscation Engine & DPI Decoy
pub struct EclipseMutator;

impl EclipseMutator {
    /// PORT HOPPING (Lompatan Acak Sinkron)
    /// Menghasilkan nomor Port selanjutnya (antara 10.000 hingga 60.000)
    /// berdasarkan "Seed Koneksi" dan "Waktu Milidetik" saat ini.
    /// Klien dan Server akan menghasilkan nomor port yang sama tanpa harus berkomunikasi!
    pub fn calculate_next_port(connection_seed: &str, current_time_ms: u64) -> u16 {
        // Kita lompat port setiap 100 milidetik (0.1 detik)
        let time_window = current_time_ms / 100;
        
        let mut hasher = Sha256::new();
        hasher.update(format!("{}-{}", connection_seed, time_window).as_bytes());
        let result = hasher.finalize();
        
        // Ambil 2 byte pertama dari Hash untuk menentukan nomor port acak
        let random_u16 = ((result[0] as u16) << 8) | (result[1] as u16);
        
        // Pastikan port berada di range dinamis (10000 - 60000)
        let next_port = 10000 + (random_u16 % 50000);
        
        debug!("ECLIPSE MATRIX: Port Hopping diaktifkan. Melompat ke UDP Port {}", next_port);
        next_port
    }

    /// DPI DECOY (Jubah Bunglon)
    /// Menyuntikkan serangkaian byte sampah di bagian depan paket yang memiliki 
    /// "Sidik Jari (Fingerprint)" persis sama dengan trafik Game Online populer.
    /// Mesin DPI Firewall negara akan terkecoh dan membiarkannya lewat.
    pub fn camouflage_packet_as_game_traffic(raw_video_packet: &[u8]) -> Vec<u8> {
        // Simulasi Sidik Jari Trafik Game Online (Misal UDP Ping milik game tertentu)
        // Header palsu sepanjang 8 bytes.
        let decoy_header: [u8; 8] = [0xFF, 0xFF, 0x47, 0x41, 0x4D, 0x45, 0x01, 0x02];
        
        let mut camouflaged_packet = Vec::with_capacity(decoy_header.len() + raw_video_packet.len());
        camouflaged_packet.extend_from_slice(&decoy_header);
        camouflaged_packet.extend_from_slice(raw_video_packet);

        debug!("ECLIPSE MATRIX: Paket Video dibungkus dengan jubah Game Trafik. Mesin DPI Firewall telah dibutakan.");
        camouflaged_packet
    }
    
    /// Fungsi untuk mencabut jubah (Decoy) di sisi penerima
    pub fn strip_decoy_header(camouflaged_packet: &[u8]) -> Result<Vec<u8>> {
        if camouflaged_packet.len() < 8 {
            return Err(anyhow::anyhow!("Paket terlalu kecil, dicurigai bukan dari Eclipse Matrix"));
        }
        
        // Buang 8 byte pertama (jubah palsu) dan kembalikan paket asli
        Ok(camouflaged_packet[8..].to_vec())
    }
}

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

    #[test]
    fn test_great_firewall_annihilation() {
        // Simulasi Klien dan Server yang disadap oleh Firewall Negara
        // Test seed — in production, seed is derived from runtime handshake
        let secret_seed = "TEST_ECLIPSE_SEED_3Z";
        let time_now = 1684320000000; // Milidetik simulasi
        
        // 1. PEMBUKTIAN PORT HOPPING
        // Klien dan Server menghitung port secara mandiri tanpa kirim pesan
        let port_klien = EclipseMutator::calculate_next_port(secret_seed, time_now);
        let port_server = EclipseMutator::calculate_next_port(secret_seed, time_now);
        
        // Port harus sinkron sempurna agar paket tidak nyasar
        assert_eq!(port_klien, port_server);
        assert!(port_klien >= 10000 && port_klien <= 60000);
        println!("PORT HOPPING BERHASIL: Klien dan Server lompat ke Port {} tanpa berunding! Firewall kehilangan jejak.", port_klien);
        
        // 2. PEMBUKTIAN DPI DECOY (Bunglon Paket)
        let paket_video_asli = vec![1, 2, 3, 4, 5]; // Ini akan diblokir Firewall jika terdeteksi
        
        // Klien membungkus paket
        let paket_berjubah = EclipseMutator::camouflage_packet_as_game_traffic(&paket_video_asli);
        
        // Firewall memindai header, melihat "0xFF 0xFF 0x47 0x41 0x4D 0x45", mengira ini game, dan DILOLOSKAN.
        assert_eq!(paket_berjubah.len(), paket_video_asli.len() + 8);
        assert_eq!(paket_berjubah[2], 0x47); // 'G'
        
        // Server menerima dan mencabut jubahnya
        let paket_diterima_server = EclipseMutator::strip_decoy_header(&paket_berjubah).unwrap();
        
        // Paket asli utuh sempurna
        assert_eq!(paket_diterima_server, paket_video_asli);
        println!("DPI DECOY BERHASIL: Paket selamat melewati Firewall dan jubah berhasil dicabut di server.");
    }
}
