// 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 core::ptr::null;

use bssl_crypto::FromFfiSlice;

use crate::{
    alpn::AlpnProtocols,
    config::ConfigurationError,
    connection::lifecycle::{
        EstablishedTlsConnection,
        TlsConnectionInHandshake, //
    },
    errors::Error,
    ffi::slice_into_ffi_raw_parts, //
};

impl<R, M> TlsConnectionInHandshake<'_, R, M> {
    /// Set ALPN protocols.
    ///
    /// Per [RFC 7301], empty protocol names, names longer than 255 bytes are invalid.
    /// Also, the total size of the ALPN protocol list must not exceed [`u16::MAX`] bytes.
    ///
    /// **This method has no effect after handshake completion.**
    ///
    /// [RFC 7301]: <https://datatracker.ietf.org/doc/html/rfc7301#section-3.1>
    pub fn set_alpn_protocols<'a>(
        &mut self,
        protocols: impl IntoIterator<Item = &'a [u8]>,
    ) -> Result<&mut Self, Error> {
        let mut protos = AlpnProtocols::default();
        for proto in protocols {
            protos
                .append_protocol(proto)
                .map_err(|_| Error::Configuration(ConfigurationError::InvalidAlpnProtocols))?;
        }
        let (protos, len) = slice_into_ffi_raw_parts(protos.as_slice());
        let rc = unsafe {
            // Safety:
            // - the validity of the handle `self.ptr()` is witnessed by `self`.
            // - the validity of ALPN string is guaranteed by `AlpnProtocols` type.
            // Note: `SSL_set_alpn_protos` flips the return value around.
            bssl_sys::SSL_set_alpn_protos(self.ptr(), protos, len)
        };
        if rc == 1 {
            Err(Error::extract_lib_err())
        } else {
            Ok(self)
        }
    }
}

/// Application-layer Protocol Negotiation.
impl<R, M> EstablishedTlsConnection<'_, R, M> {
    /// Get the selected Application-layer Protocol.
    ///
    /// This function returns [`None`] when no ALPN protocol was negotiated.
    pub fn get_selected_alpn(&self) -> Option<&[u8]> {
        let mut name = null();
        let mut len = 0;
        unsafe {
            // Safety: the validity of the handle `self.ptr()` is witnessed by `self`.
            bssl_sys::SSL_get0_alpn_selected(self.ptr(), &raw mut name, &raw mut len);
        }
        let Ok(len) = usize::try_from(len) else {
            panic!("invalid slice length")
        };
        let proto = unsafe {
            // Safety:
            // - `self` outlives the output slice.
            // - `name` is generated by BoringSSL.
            u8::from_ffi_ptr(name, len)
        };
        (!proto.is_empty()).then_some(proto)
    }
}
