use ldpc::benchmark::get_or_generate_cached_code;
use ldpc::channel::AwgnChannel;
use ldpc::code::GenerationMethod;
use ldpc::decoder::{build_decoder, DecoderConfig, DecoderMethod};
use ldpc::encoder::{build_encoder, EncodingMethod};
use ldpc::image_sim::transmit_image;

// fn main() -> ldpc::Result<()> {
//     let n = 1944;
//     let k = 972;
//     let wc = 3;
//     let wr = 6;
//
//     println!("Transmission d'image via code LDPC");
//
//     let code_mn = get_or_generate_cached_code(
//         n,
//         k,
//         wc,
//         wr,
//         GenerationMethod::MacKayNeal { max_attempts: 5000 },
//     )?;
//
//     let mut code = code_mn;
//     let encoder = build_encoder(&mut code, EncodingMethod::Systematic)?;
//
//     let config = DecoderConfig {
//         max_iterations: 50,
//         early_stopping: true,
//     };
//
//     // Sum-Product
//     let decoder = build_decoder(&code, DecoderMethod::SumProduct, config);
//
//     let channel = AwgnChannel::new(2.0, code.rate())?;
//
//     transmit_image(
//         "test.png",
//         "noisy_out.png",
//         "decoded_out.png",
//         &*encoder,
//         &*decoder,
//         &channel,
//     )?;
//
//     Ok(())
// }

use clap::Parser;
use ldpc::benchmark2::{run_massive_campaign, CampaignConfig, CodeScenario};

#[derive(Parser, Debug)]
#[command(author, version, about = "Laboratoire de test LDPC - TIPE")]
struct Args {
    #[arg(short, long, default_value_t = 1000)]
    trials: usize,

    /// Générer les fichiers .dot pour visualiser les graphes de Tanner
    #[arg(long, default_value_t = false)]
    export_graph: bool,
}

fn main() -> ldpc::Result<()> {
    let args = Args::parse();
    let snrs = vec![1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.5, 4.0];
    let mut scenarios = Vec::new();

    // -------------------------------------------------------------------------
    // SCÉNARIO "TOY MODEL" : Spécial pour ton document Typst
    // Un code minuscule R=1/2 avec n=24, k=12, m=12.
    // Lisible sur une feuille A4.
    // -------------------------------------------------------------------------
    if args.export_graph {
        scenarios.push(CodeScenario {
            name: "ToyModel_Typst_N24".into(),
            n: 24,
            k: 12,
            wc: 3,
            wr: 6,
            method: GenerationMethod::Gallager,
        });
    }

    // Les vrais tests pour tes courbes de performances
    scenarios.push(CodeScenario {
        name: "Gallager_N1296_R05".into(),
        n: 1296,
        k: 648,
        wc: 3,
        wr: 6,
        method: GenerationMethod::Gallager,
    });

    scenarios.push(CodeScenario {
        name: "MacKay_N1296_R05".into(),
        n: 1296,
        k: 648,
        wc: 3,
        wr: 6,
        method: GenerationMethod::MacKayNeal { max_attempts: 1000 },
    });

    let config = CampaignConfig {
        scenarios,
        snr_range: snrs,
        n_trials: args.trials,
        max_iterations: 50,
        output_csv: "tipe_results.csv".into(),
        export_graph: args.export_graph,
    };

    run_massive_campaign(config)?;

    Ok(())
}

// use ldpc::benchmark::run_simulation;
//
// fn main() -> ldpc::Result<()> {
//     let n = 1944;
//     let k = 972;
//     let wc = 3;
//     let wr = 6;
//
//     println!("Benchmark: MacKayNeal vs Gallager");
//     println!();
//
//     println!("Test 1: Génération MacKayNeal\n");
//     let code_mn = get_or_generate_cached_code(
//         n,
//         k,
//         wc,
//         wr,
//         GenerationMethod::MacKayNeal { max_attempts: 5000 },
//     )?;
//
//     run_simulation(code_mn)?;
//
//     println!("\nTest 2 : Génération Gallager\n");
//     let code_gal = get_or_generate_cached_code(n, k, wc, wr, GenerationMethod::Gallager)?;
//     run_simulation(code_gal)?;
//
//     Ok(())
// }
