// Copyright 2026 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{
    future::Future,
    pin::Pin,
    sync::{
        Arc,
        Mutex, //
    },
    task::{
        Context,
        Poll, //
    },
};

use bssl_crypto::ecdsa::ParsedPrivateKey;
use bssl_x509::{
    certificates::X509Certificate,
    params::Trust,
    store::X509StoreBuilder, //
};
use futures::channel::oneshot;

use super::{
    CA,
    P256_SERVER_CERT, //
};
use crate::{
    context::TlsContextBuilder,
    credentials::{
        AsyncPrivateKeyDelegate,
        Certificate,
        CertificateVerificationMode,
        SignatureAlgorithm,
        TlsCredentialBuilder, //
    },
    errors::TlsRetryReason,
    io::IoStatus,
    tests::create_mock_pipe, //
};

#[test]
fn test_private_key_methods() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let ca = Certificate::parse_one_from_pem(CA, None)?;
    let server_cert = Certificate::parse_one_from_pem(P256_SERVER_CERT, None)?;

    let (client_to_server_tx, client_to_server_rx) = oneshot::channel::<()>();
    let (server_to_client_tx, server_to_client_rx) = oneshot::channel::<()>();

    let private_key_method = MyPrivateKeyMethod {
        key: crate::tests::P256_SERVER_KEY_DER,
        client_to_server_rx: Arc::new(Mutex::new(Some(client_to_server_rx))),
        server_to_client_tx: Arc::new(Mutex::new(Some(server_to_client_tx))),
    };

    struct MyPrivateKeyMethod {
        key: &'static [u8],
        client_to_server_rx: Arc<Mutex<Option<oneshot::Receiver<()>>>>,
        server_to_client_tx: Arc<Mutex<Option<oneshot::Sender<()>>>>,
    }

    impl AsyncPrivateKeyDelegate for MyPrivateKeyMethod {
        type DecryptOp = Pin<Box<dyn Send + Sync + Future<Output = Option<Vec<u8>>>>>;
        type SignOp = Pin<Box<dyn Send + Sync + Future<Output = Option<Vec<u8>>>>>;
        fn sign(&self, message: &[u8], algorithm: SignatureAlgorithm) -> Self::SignOp {
            let message = message.to_vec();
            let Some(ParsedPrivateKey::P256(key)) = ParsedPrivateKey::from_der(self.key) else {
                panic!()
            };
            let client_to_server_rx = self.client_to_server_rx.clone();
            let server_to_client_tx = self.server_to_client_tx.clone();
            Box::pin(async move {
                let tx = server_to_client_tx.lock().unwrap().take();
                if let Some(tx) = tx {
                    tx.send(()).unwrap();
                }

                let rx = client_to_server_rx.lock().unwrap().take();
                if let Some(rx) = rx {
                    rx.await.unwrap();
                }

                assert!(matches!(
                    algorithm,
                    SignatureAlgorithm::EcdsaSecp256r1Sha256
                ));
                Some(key.sign(&message))
            })
        }

        fn decrypt(&self, _: &[u8]) -> Self::DecryptOp {
            unreachable!()
        }
    }

    let mut server_ctx_builder = TlsContextBuilder::new_tls();
    let server_cred = {
        let mut builder = TlsCredentialBuilder::new();
        builder
            .with_certificate_chain(&[server_cert, ca])?
            .with_private_key_delegate(Some(crate::credentials::AsyncPrivateKeyDelegateAdapter(
                private_key_method,
            )));
        builder.build().unwrap()
    };
    server_ctx_builder.with_credential(server_cred)?;
    let server_ctx = server_ctx_builder.build();
    let mut server_conn = server_ctx.new_server_connection(None)?.build();

    let mut client_ctx_builder = TlsContextBuilder::new_tls();
    let mut cert_store = X509StoreBuilder::new();
    cert_store
        .set_trust(Trust::SslServer)?
        .add_cert(X509Certificate::parse_one_from_pem(CA)?)?;
    let cert_store = cert_store.build();
    client_ctx_builder.with_certificate_store(&cert_store);
    let client_ctx = client_ctx_builder.build();
    let mut client_conn = client_ctx.new_client_connection(None)?;
    client_conn.with_certificate_verification_mode(CertificateVerificationMode::PeerCertMandatory);
    let mut client_conn = client_conn.build();
    client_conn
        .in_handshake()
        .unwrap()
        .set_host("www.google.com")?;

    let (client_socket, server_socket, mut executor) = create_mock_pipe();
    client_conn.set_io(client_socket)?;
    server_conn.set_io(server_socket)?;

    let mut server_task = async move || -> Result<(), crate::errors::Error> {
        loop {
            match server_conn.async_handshake().await {
                Ok(None) => break,
                Ok(Some(TlsRetryReason::PendingPrivateKeyOperation)) => {
                    struct Yield(bool);
                    impl std::future::Future for Yield {
                        type Output = ();
                        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
                            if self.0 {
                                return Poll::Ready(());
                            }
                            self.0 = true;
                            cx.waker().wake_by_ref();
                            Poll::Pending
                        }
                    }
                    Yield(false).await;
                }
                res => panic!("Unexpected handshake result: {:?}", res),
            }
        }

        let mut message = [0; 21];
        assert!(matches!(
            server_conn.as_pin_mut().async_read(&mut message).await?,
            IoStatus::Ok(21)
        ));
        assert_eq!(message, *b"BoringSSL is awesome!");
        server_conn.as_pin_mut().async_shutdown().await?;
        Ok(())
    };

    let client_task = async move || -> Result<(), crate::errors::Error> {
        let res = client_conn.do_handshake();
        assert!(
            matches!(res, Ok(Some(TlsRetryReason::WantRead))),
            "Expected WantRead, got {:?}",
            res
        );

        server_to_client_rx.await.unwrap();
        client_to_server_tx.send(()).unwrap();

        client_conn
            .as_pin_mut()
            .async_write(b"BoringSSL is awesome!")
            .await?;

        client_conn.as_pin_mut().async_shutdown().await?;
        Ok(())
    };

    let test_closure = async move || -> Result<(), crate::errors::Error> {
        futures::future::try_join(server_task(), client_task()).await?;
        Ok(())
    };

    executor.run(test_closure())?;

    Ok(())
}
