#![doc = include_str!("../README.md")]
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::missing_errors_doc)]

use rcgen::{CertifiedKey, generate_simple_self_signed};
use std::error::Error;
use std::fs::File;
use std::io::Write;
use std::path::Path;

fn write_certs(
    cert_dir_path: impl AsRef<Path>,
    cert: &[u8],
    key: &[u8],
) -> Result<(), Box<dyn Error>> {
    std::fs::create_dir_all(&cert_dir_path)?;

    let cert_path = cert_dir_path.as_ref().join("crt.pem");
    let key_path = cert_dir_path.as_ref().join("key.pem");

    let mut cert_file = File::create(cert_path)?;
    let mut key_file = File::create(key_path)?;

    cert_file.write_all(cert)?;
    key_file.write_all(key)?;

    Ok(())
}

/// writes crt.pem and key.pem to directory
pub fn generate_self_signed_localhost_certs(
    cert_dir_path: impl AsRef<Path>,
) -> Result<(), Box<dyn Error>> {
    let subject_alt_names = vec!["localhost".to_string()];

    let CertifiedKey { cert, signing_key } = match generate_simple_self_signed(subject_alt_names) {
        Ok(ck) => {
            tracing::info!("generated self-signed localhost cert");
            ck
        }
        Err(err) => {
            tracing::error!("failed to generate self-signed localhost cert");
            return Err(err.into());
        }
    };

    let cert = cert.pem();
    let key = signing_key.serialize_pem();

    write_certs(cert_dir_path, cert.as_bytes(), key.as_bytes())?;

    Ok(())
}
