//! Test file output routines for the feature-check test generator.

use std::error;
use std::io::Write;
use std::path;

use config_diag::ConfigDiag;
use expect_exit::ExpectedResult;

use crate::defs;

/// Render the test data into the specified output file.
pub fn write_output_file(
    cfg: &defs::Config,
    template: handlebars::Handlebars,
    test_data: defs::TestData,
) -> Result<(), Box<dyn error::Error>> {
    let output = template
        .render(defs::TEMPLATE_NAME, &test_data)
        .expect_result(|| {
            format!(
                "Could not render the {} template using the {} data",
                cfg.template_path, cfg.data_path
            )
        })?;
    cfg.diag(|| {
        format!(
            "About to write {} characters to {}",
            output.len(),
            cfg.output_path
        )
    });

    let opath = path::Path::new(&cfg.output_path);
    let odir = opath.parent().expect_result(|| {
        format!(
            "Could not determine the parent directory of {}",
            cfg.output_path
        )
    })?;
    let mut tempf = tempfile::NamedTempFile::new_in(odir)?;
    let tempf_path = tempf.path().display().to_string();
    cfg.diag(|| format!("Using {} as a temporary output file", tempf_path));
    tempf
        .write_all(output.as_bytes())
        .expect_result(|| format!("Could not write to the {} temporary file", tempf_path))?;
    cfg.diag(|| "Overwriting the output file".to_string());
    tempf.persist(&cfg.output_path).expect_result(|| {
        format!(
            "Could not rename the {} temporary file to {}",
            tempf_path, cfg.output_path
        )
    })?;
    Ok(())
}
