#![deny(missing_docs)]
// SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
// SPDX-License-Identifier: BSD-2-Clause
//! Generate the POSIX shell test suite for remrun.
//!
//! Read the JSON test definitions and convert them to a POSIX shell program.

use std::fs;

use eyre::{Result, WrapErr as _, bail};
use itertools::Itertools as _;
use log::{debug, info};

use generate_tests::builder;
use generate_tests::loader;

mod cli;

#[expect(clippy::print_stdout, reason = "support `--output-file -`")]
fn main() -> Result<()> {
    let cfg = cli::parse_args().context("Could not parse the command-line options")?;
    debug!("starting up");
    let test_defs = loader::load_defs(&cfg).context("Could not load the test definitions")?;
    debug!("loaded {count} tests", count = test_defs.tests().len());
    debug!(
        "{defs}",
        defs = test_defs
            .tests()
            .iter()
            .map(|tdef| format!("- {title}", title = tdef.title()))
            .join("\n")
    );

    let contents = builder::generate(&cfg, &test_defs)
        .context("Could not generate the test file's contents")?;
    if let Some(output_path) = cfg.output_path() {
        if cfg.check_only() {
            info!("Reading the current contents of {output_path}");
            let current = fs::read_to_string(output_path)
                .with_context(|| format!("Could not read the current context of {output_path}"))?;
            if current == contents {
                info!("No need to update {output_path}");
                return Ok(());
            }
            bail!("Need to update {output_path}");
        }

        debug!(
            "Writing {count} bytes of output to {output_path}",
            count = contents.len()
        );

        fs::write(output_path, &contents).with_context(|| {
            format!(
                "Could not write {count} bytes to {output_path}",
                count = contents.len()
            )
        })?;
    } else {
        debug!(
            "Writing {count} bytes of output to the standard output stream",
            count = contents.len()
        );
        print!("{contents}");
    }
    Ok(())
}
