use hagrid_database::types::Fingerprint;
use hagrid_database::{Database, Query, Sqlite};
use std::convert::TryInto;
use std::path::Path;

pub(crate) fn run(
    db_file_path: impl AsRef<Path>,
    query: &Query,
    all_bindings: bool,
    mut all: bool,
) -> anyhow::Result<()> {
    let db = &Sqlite::new_file(
        &db_file_path,
        Sqlite::log_dir_path_from_db_file_path(&db_file_path)?,
    )?;

    match query {
        Query::ByFingerprint(_) | Query::ByKeyID(_) => {
            eprintln!(
                "Fingerprint or KeyID given, deleting key and all \
                       bindings."
            );
            all = true;
        }
        _ => (),
    }

    let tpk = db
        .lookup(query)?
        .ok_or_else(|| anyhow::format_err!("No TPK matching {:?}", query))?;

    let fp: Fingerprint = tpk.fingerprint().try_into()?;
    let mut results = Vec::new();

    // First, delete the bindings.
    if all_bindings || all {
        results.push(("all bindings".into(), db.set_email_unpublished_all(&fp)));
    } else if let Query::ByEmail(email) = query {
        results.push((email.to_string(), db.set_email_unpublished(&fp, email)));
    } else {
        unreachable!()
    }

    // Now delete the key(s) itself.
    if all {
        // TODO
        /*for skb in tpk.subkeys() {
            results.push(
                (skb.subkey().fingerprint().to_keyid().to_string(),
                 db.unlink_kid(&skb.subkey().fingerprint().try_into()?,
                               &fp)));
            results.push(
                (skb.subkey().fingerprint().to_string(),
                 db.unlink_fpr(&skb.subkey().fingerprint().try_into()?,
                               &fp)));
        }

        results.push(
            (tpk.fingerprint().to_keyid().to_string(),
             db.unlink_kid(&tpk.fingerprint().try_into()?,
                           &fp)));
        results.push(
            (tpk.fingerprint().to_string(),
             db.update(&fp, None)));
        */
    }

    let mut err = Ok(());
    for (slug, result) in results {
        eprintln!(
            "{}: {}",
            slug,
            if let Err(ref e) = result {
                e.to_string()
            } else {
                "Deleted".into()
            }
        );
        if err.is_ok() {
            if let Err(e) = result {
                err = Err(e);
            }
        }
    }

    err
}
