// 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 alloc::boxed::Box;
use core::{
    ffi::c_int,

    ptr::{
        NonNull,
        null_mut, //
    }, //
};

use once_cell::sync::Lazy;

use crate::{
    MethodsRef,
    PrivateKeyMethods,
    abort_on_panic,
    connection::methods::private_key_op_from_ssl,
    credentials::{
        DecryptionOperation,
        PrivateKeyDelegate,
        PrivateKeyOperationResult,
        SignatureOperation,
        waker_data_from_ssl, //
    },
    ffi::{
        sanitise_mut_byteslice,
        sanitize_slice, //
    },
    methods::drop_box_rust_methods, //
};

pub(super) static TLS_CREDENTIAL_METHOD: Lazy<c_int> = Lazy::new(|| unsafe {
    // Safety: this a one-time registration uses only valid function pointers.
    let ret = bssl_sys::SSL_CREDENTIAL_get_ex_new_index(
        0,
        null_mut(),
        null_mut(),
        None,
        Some(drop_box_rust_methods::<RustCredentialMethods>),
    );
    if ret < 0 {
        panic!("Failed to register TLS Credential ex-data")
    } else {
        ret
    }
});

#[derive(Default)]
pub(crate) struct RustCredentialMethods {
    pub(crate) private_key_methods: Option<Box<dyn PrivateKeyDelegate>>,
}

impl MethodsRef for RustCredentialMethods {
    unsafe extern "C" fn from_ssl<'a>(ssl: *mut bssl_sys::SSL) -> Option<&'a Self> {
        unsafe {
            // Safety: `ssl` is valid per BoringSSL invariant.
            let cred = bssl_sys::SSL_get0_selected_credential(ssl);
            if cred.is_null() {
                return None;
            }
            // Safety: `cred` is valid and originated from `TlsCredential::new`.
            let methods = bssl_sys::SSL_CREDENTIAL_get_ex_data(cred, *TLS_CREDENTIAL_METHOD);
            if methods.is_null() {
                return None;
            }
            // Safety: `methods` is originated from `Box::into_raw`.
            Some(&*(methods as *const RustCredentialMethods))
        }
    }
}

impl PrivateKeyMethods for RustCredentialMethods {
    fn private_key_methods(&self) -> Option<&dyn PrivateKeyDelegate> {
        self.private_key_methods.as_deref()
    }
}

macro_rules! private_key_method_prelude {
    ($M:ty, $ssl:ident => $context:ident, $private_key_methods:ident, $task:ident) => {
        let Some(ssl) = NonNull::new($ssl) else {
            return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
        };
        let Some(methods) = (unsafe {
            // Safety: `ssl` outlives `methods` and must be valid by BoringSSL contract.
            <$M>::from_ssl(ssl.as_ptr())
        }) else {
            return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
        };
        let waker = unsafe {
            // Safety: `ssl` must be constructed by `TlsConnection` as this is called from
            waker_data_from_ssl(ssl)
        };
        let mut $context = if let Some(waker) = &waker {
            Some(core::task::Context::from_waker(waker))
        } else {
            None
        };
        #[allow(unused_mut)]
        let $task = unsafe {
            // Safety: `ssl` must be constructed by `TlsConnection` as this is called from
            private_key_op_from_ssl(ssl)
        };
        let Some($private_key_methods) = methods.private_key_methods() else {
            return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
        };
    };
}

pub(crate) unsafe extern "C" fn sign<Method: PrivateKeyMethods>(
    ssl: *mut bssl_sys::SSL,
    out: *mut u8,
    out_len: *mut usize,
    max_out: usize,
    sig_alg: u16,
    msg: *const u8,
    msg_len: usize,
) -> bssl_sys::ssl_private_key_result_t {
    private_key_method_prelude!(Method, ssl => context, private_key_methods, task);
    if task.is_some() {
        abort_on_panic(|| {
            let _ = task.take();
        });
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    }

    // Unwind-safety: later when panic happens, we detach the poisoned private key method
    // without calling destructor.
    let algorithm = match sig_alg.try_into() {
        Ok(sig_alg) => sig_alg,
        // TODO(@xfding) maybe we should log this error?
        Err(_) => return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure,
    };
    let Some(output) = (unsafe {
        // Safety: the slice will only be used within this callback.
        sanitise_mut_byteslice(out, max_out)
    }) else {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    };
    if output.is_empty() {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    }
    let Some(message) = (unsafe {
        // Safety: `msg` outlives `message` because it is owned by BoringSSL.
        sanitize_slice(msg, msg_len)
    }) else {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    };
    // Unwind-safety: when panic happens, we will not inspect the `output` buffer.
    abort_on_panic(move || {
        let sign_op = SignatureOperation {
            output,
            message,
            algorithm,
        };
        let mut outstanding_task = private_key_methods.sign(sign_op);
        match outstanding_task.complete(context.as_mut(), output) {
            PrivateKeyOperationResult::Success(len) => {
                unsafe {
                    // Safety: `out_len` is a valid pointer by BoringSSL invariant.
                    *out_len = len;
                }
                bssl_sys::ssl_private_key_result_t_ssl_private_key_success
            }
            PrivateKeyOperationResult::Pending => {
                *task = Some(outstanding_task);
                bssl_sys::ssl_private_key_result_t_ssl_private_key_retry
            }
            PrivateKeyOperationResult::Error => {
                bssl_sys::ssl_private_key_result_t_ssl_private_key_failure
            }
        }
    })
}

pub(crate) unsafe extern "C" fn decrypt<Method: PrivateKeyMethods>(
    ssl: *mut bssl_sys::SSL,
    out: *mut u8,
    out_len: *mut usize,
    max_out: usize,
    ciphertext: *const u8,
    ciphertext_len: usize,
) -> bssl_sys::ssl_private_key_result_t {
    private_key_method_prelude!(Method, ssl => context, private_key_methods, task);
    if task.is_some() {
        abort_on_panic(|| {
            let _ = task.take();
        });
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    }

    // Unwind-safety: later when panic happens, we detach the poisoned private key method
    // without calling destructor.
    let Some(output) = (unsafe {
        // Safety: the slice will only be used within this callback.
        sanitise_mut_byteslice(out, max_out)
    }) else {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    };
    if output.is_empty() {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    }
    let Some(ciphertext) = (unsafe {
        // Safety: `ciphertext` is now owned by BoringSSL and outlives the slice.
        sanitize_slice(ciphertext, ciphertext_len)
    }) else {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    };
    // Unwind-safety: when panic happens, we will not inspect the `output` buffer.
    abort_on_panic(move || {
        let decrypt_op = DecryptionOperation { output, ciphertext };
        let mut outstanding_task = private_key_methods.decrypt(decrypt_op);
        match outstanding_task.complete(context.as_mut(), output) {
            PrivateKeyOperationResult::Success(len) => {
                unsafe {
                    // Safety: `out_len` is a valid pointer by BoringSSL invariant.
                    *out_len = len;
                }
                bssl_sys::ssl_private_key_result_t_ssl_private_key_success
            }
            PrivateKeyOperationResult::Pending => {
                *task = Some(outstanding_task);
                bssl_sys::ssl_private_key_result_t_ssl_private_key_retry
            }
            PrivateKeyOperationResult::Error => {
                bssl_sys::ssl_private_key_result_t_ssl_private_key_failure
            }
        }
    })
}

pub(crate) unsafe extern "C" fn complete<Method: PrivateKeyMethods>(
    ssl: *mut bssl_sys::SSL,
    out: *mut u8,
    out_len: *mut usize,
    max_out: usize,
) -> bssl_sys::ssl_private_key_result_t {
    private_key_method_prelude!(Method, ssl => context, _private_key_methods, task);

    // Unwind-safety: later when panic happens, we detach the poisoned private key method
    // without calling destructor.
    let Some(output) = (unsafe {
        // Safety: the slice will only be used within this callback.
        sanitise_mut_byteslice(out, max_out)
    }) else {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    };
    if output.is_empty() {
        return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
    }
    // Unwind-safety: when panic happens, we will not inspect the `output` buffer.
    abort_on_panic(move || {
        let Some(outstanding_task) = task else {
            return bssl_sys::ssl_private_key_result_t_ssl_private_key_failure;
        };
        match outstanding_task.complete(context.as_mut(), output) {
            PrivateKeyOperationResult::Success(len) => {
                unsafe {
                    // Safety: `out_len` is a valid pointer by BoringSSL invariant.
                    *out_len = len;
                }
                bssl_sys::ssl_private_key_result_t_ssl_private_key_success
            }
            PrivateKeyOperationResult::Pending => {
                bssl_sys::ssl_private_key_result_t_ssl_private_key_retry
            }
            PrivateKeyOperationResult::Error => {
                bssl_sys::ssl_private_key_result_t_ssl_private_key_failure
            }
        }
    })
}

pub(super) const PRIVATE_KEY_METHODS: *const bssl_sys::SSL_PRIVATE_KEY_METHOD = {
    &bssl_sys::SSL_PRIVATE_KEY_METHOD {
        sign: Some(sign::<RustCredentialMethods>),
        decrypt: Some(decrypt::<RustCredentialMethods>),
        complete: Some(complete::<RustCredentialMethods>),
    } as _
};
