#[cfg(feature = "compare")]
use std::env;
#[cfg(feature = "compare")]
use std::fs::File;
#[cfg(feature = "compare")]
use std::io::Write;
#[cfg(feature = "compare")]
use std::path::Path;

#[cfg(feature = "compare")]
use walkdir::WalkDir;

#[cfg(feature = "compare")]
fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let destination = Path::new(&out_dir).join("tests.rs");
    let mut test_file = File::create(&destination).unwrap();

    write_header(&mut test_file);

    let test_files = WalkDir::new("org_mode_samples")
        .into_iter()
        .filter(|e| match e {
            Ok(dir_entry) => {
                dir_entry.file_type().is_file()
                    && Path::new(dir_entry.file_name())
                        .extension()
                        .map(|ext| ext.to_ascii_lowercase() == "org")
                        .unwrap_or(false)
            }
            Err(_) => true,
        })
        .collect::<Result<Vec<_>, _>>()
        .unwrap();
    for test in test_files {
        write_test(&mut test_file, &test);
    }
}

#[cfg(not(feature = "compare"))]
fn main() {}

#[cfg(feature = "compare")]
fn write_test(test_file: &mut File, test: &walkdir::DirEntry) {
    let test_name = test
        .path()
        .strip_prefix("org_mode_samples/")
        .expect("Paths should be under org_mode_samples/")
        .to_string_lossy()
        .to_lowercase()
        .strip_suffix(".org")
        .expect("Should have .org extension")
        .replace("/", "_");
    let test_name = format!("autogen_{}", test_name);

    if let Some(_reason) = is_expect_fail(test_name.as_str()) {
        write!(test_file, "#[ignore]\n").unwrap();
    }
    write!(
        test_file,
        include_str!("./tests/test_template"),
        name = test_name,
        path = test.path().display()
    )
    .unwrap();
}

#[cfg(feature = "compare")]
fn write_header(test_file: &mut File) {
    write!(
        test_file,
        r#"
#[feature(exit_status_error)]
use organic::compare_document;
use organic::parser::parse;
use organic::emacs_parse_anonymous_org_document;
use organic::parser::sexp::sexp_with_padding;

"#
    )
    .unwrap();
}

#[cfg(feature = "compare")]
fn is_expect_fail(name: &str) -> Option<&str> {
    match name {
        "autogen_greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."),
        "autogen_element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."),
        "autogen_lesser_element_paragraphs_paragraph_with_backslash_line_breaks" => Some("The text we're getting out of the parse tree is already processed to remove line breaks, so our comparison needs to take that into account."),
        _ => None,
    }
}