// SPDX-FileCopyrightText: Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0

use std::time::SystemTime;

use pgp::{
    packet::{Signature, SignatureType},
    types::KeyDetails,
};
use rpgpie::{certificate::Certificate, key::ComponentKeyPub, message::MessageResult};

pub(crate) fn to_verification(
    signature: &Signature,
    cert: &Certificate,
    key: &ComponentKeyPub,
    source: Option<&str>,
) -> sop::ops::Verification {
    let ct: SystemTime = (signature.created().expect("FIXME")).into();

    let key_fp = hex::encode(key.fingerprint().as_bytes());
    let cert_fp = hex::encode(cert.fingerprint().as_bytes());

    let mode = match signature.typ() {
        Some(SignatureType::Binary) => sop::ops::SignatureMode::Binary,
        Some(SignatureType::Text) => sop::ops::SignatureMode::Text,
        _ => panic!("unexpected data signature type"),
    };

    let mut ver = sop::ops::Verification::new(ct, key_fp, cert_fp, mode, None).expect("FIXME");

    if let Some(source) = source {
        ver.add_signer(source);
    }

    ver
}

pub(crate) fn result_to_verifications(mr: &MessageResult) -> Vec<sop::ops::Verification> {
    mr.validated
        .iter()
        // FIXME: add source information if available
        .map(|(cert, key, sig)| to_verification(sig, cert, key, None))
        .collect()
}

pub(crate) struct DebugWrapper<'a>(
    pub std::io::BufReader<&'a mut (dyn std::io::Read + Send + Sync)>,
);

impl std::io::Read for DebugWrapper<'_> {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        self.0.read(buf)
    }
}

impl std::io::BufRead for DebugWrapper<'_> {
    fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
        self.0.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.0.consume(amt);
    }
}

impl std::fmt::Debug for DebugWrapper<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("DebugWrapper").finish()
    }
}

// pub(crate) fn accept(t: &mut (dyn std::io::Read + Send + Sync)) {
//     accept_debug(DebugWrapper(std::io::BufReader::new(t)))
// }
//
// fn accept_debug<T: std::io::BufRead + std::fmt::Debug>(t: T) {
//     todo!();
// }
