use std::env;

use clap::CommandFactory;
use clap_complete::Shell;

use anyhow::Result;

use sequoia_man::asset_out_dir;

pub mod cli {
    include!("src/cli/mod.rs");
}

// To avoid adding a build dependency on sequoia-openpgp, we mock the
// bits of openpgp that the CLI module uses.
pub mod openpgp {
    #[derive(Clone, Debug)]
    pub struct KeyHandle {
    }

    impl From<&str> for KeyHandle {
        fn from(_: &str) -> KeyHandle {
            KeyHandle {}
        }
    }
}

fn main() {
    let mut cli = cli::build(false);

    git_version();
    completions();
    generate_man_pages(&mut cli).expect("can generate man pages");
}

fn git_version() {
    // Emit the "cargo:" instructions including
    // "cargo:rustc-env=VERGEN_GIT_DESCRIBE=<DESCRIBE>".
    //
    // If the source directory does not contain a git repository,
    // e.g., because the code was extracted from a tarball, this
    // produces an `Error` result, which we ignore, and
    // `VERGEN_GIT_DESCRIBE` is not set.  That's okay, because we are
    // careful to only use `VERGEN_GIT_DESCRIBE` if it is actually
    // set.
    let _ = vergen::EmitBuilder::builder()
        // VERGEN_GIT_DESCRIBE
        .git_describe(/* dirty */ true, /* tags */ false, None)
        // Don't emit placeholder values for the git version if the
        // git repository is not present.
        .fail_on_error()
        .emit();
}

fn completions() {
    // Generate shell completions
    let outdir = match std::env::var_os("CARGO_TARGET_DIR") {
        None => {
            println!("cargo:warning=Not generating completion files, \
                      environment variable CARGO_TARGET_DIR not set");
            return;
        }
        Some(outdir) => outdir,
    };

    std::fs::create_dir_all(&outdir).unwrap();

    let mut cli = cli::Cli::command();

    for shell in &[Shell::Bash, Shell::Fish, Shell::Zsh,
                   Shell::PowerShell, Shell::Elvish] {
        let path = clap_complete::generate_to(
            *shell, &mut cli, "sq-git", &outdir).unwrap();
        println!("cargo:warning=generated completion file {:?}", path);
    };
}

/// Generates man pages.
fn generate_man_pages(cli: &mut clap::Command) -> Result<()> {
    let version = env!("CARGO_PKG_VERSION");
    let mut builder = sequoia_man::man::Builder::new(cli, version, None);
    builder.see_also(
        &[ "For the full documentation see <https://sequoia-pgp.gitlab.io/sequoia-git>." ]);

    let man_pages = asset_out_dir("man-pages")?;

    sequoia_man::generate_man_pages(&man_pages, &builder).unwrap();
    Ok(())
}
