#[test]
fn codegen() {
    const DICT: &[u8] = include_bytes!("../assets/words.csv");

    let mut map_content = vec![];
    generate_map(&mut map_content, "WORD", DICT);
    let map_content = String::from_utf8(map_content).unwrap();
    let map_content = codegenrs::rustfmt(&map_content, None).unwrap();
    // Symlink handles `../benches/benches/map_codegen.rs`
    snapbox::assert_data_eq!(&map_content, snapbox::file!["../src/word_codegen.rs"].raw());

    let mut aho_corasick_content = vec![];
    generate_aho_corasick(&mut aho_corasick_content, "Word", DICT);
    let aho_corasick_content = String::from_utf8(aho_corasick_content).unwrap();
    let aho_corasick_content = codegenrs::rustfmt(&aho_corasick_content, None).unwrap();
    snapbox::assert_data_eq!(
        &aho_corasick_content,
        snapbox::file!["../benches/benches/aho_corasick_codegen.rs"].raw()
    );
}

fn generate_map<W: std::io::Write>(file: &mut W, name: &str, dict: &[u8]) {
    writeln!(
        file,
        "// This file is @generated by {}",
        file!().replace('\\', "/")
    )
    .unwrap();
    writeln!(file, "#![allow(clippy::unreadable_literal)]",).unwrap();
    writeln!(file, "#![allow(unreachable_pub)]",).unwrap();
    writeln!(file).unwrap();

    let records: Vec<_> = csv::ReaderBuilder::new()
        .has_headers(false)
        .flexible(true)
        .from_reader(dict)
        .records()
        .map(|r| r.unwrap())
        .collect();
    dictgen::DictGen::new()
        .name(name)
        .value_type("&[&str]")
        .map()
        .write(
            file,
            records.iter().map(|record| {
                let mut record_fields = record.iter();
                let key = record_fields.next().unwrap();
                let value = format!(
                    "&[{}]",
                    itertools::join(record_fields.map(|field| format!(r#""{field}""#)), ", ")
                );
                (key, value)
            }),
        )
        .unwrap();
}

fn generate_aho_corasick<W: std::io::Write>(file: &mut W, name: &str, dict: &[u8]) {
    writeln!(
        file,
        "// This file is @generated by {}",
        file!().replace('\\', "/")
    )
    .unwrap();
    writeln!(file, "#![allow(clippy::unreadable_literal)]",).unwrap();
    writeln!(file, "#![allow(clippy::redundant_static_lifetimes)]",).unwrap();
    writeln!(file, "#![allow(unreachable_pub)]",).unwrap();
    writeln!(file).unwrap();

    let records: Vec<_> = csv::ReaderBuilder::new()
        .has_headers(false)
        .flexible(true)
        .from_reader(dict)
        .records()
        .map(|r| r.unwrap())
        .collect();
    dictgen::DictGen::new()
        .name(name)
        .value_type("&'static [&'static str]")
        .aho_corasick()
        .write(
            file,
            records.iter().map(|record| {
                let mut record_fields = record.iter();
                let key = record_fields.next().unwrap();
                let value = format!(
                    "&[{}]",
                    itertools::join(record_fields.map(|field| format!(r#""{field}""#)), ", ")
                );
                (key, value)
            }),
        )
        .unwrap();
}