// 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.

//! TLS Connection transport settings
//!

use core::mem::{MaybeUninit, transmute};

use crate::{
    check_lib_error,
    check_tls_error,
    config::ConfigurationError,
    connection::{
        TlsConnection,
        TlsConnectionBuilder,
        methods::HasTlsConnectionMethod, //
    },
    context::HasBasicIo,
    errors::Error,
    io::{
        AbstractReader,
        AbstractSocket,
        AbstractWriter,
        RustBio, //
    }, //
};

/// # Transport configurations
///
/// These are the methods to configure the underlying IO drivers and transport configurations.
impl<R, M> TlsConnection<R, M>
where
    M: HasBasicIo + HasTlsConnectionMethod,
{
    /// Set up underlying transport driver.
    pub fn set_io<S: 'static + AbstractSocket>(&mut self, socket: S) -> Result<&mut Self, Error> {
        let bio = RustBio::new_duplex(socket)?;
        unsafe {
            // Safety: the additional ref-count is to compensate for `SSL` taking ownership.
            bssl_sys::BIO_up_ref(bio.ptr());
            // Safety: the `bio` pointer has been sanitised and `self.0` is still valid.
            bssl_sys::SSL_set_bio(self.ptr(), bio.ptr(), bio.ptr());
        }
        self.get_connection_methods().bio = Some(bio);
        Ok(self)
    }

    /// Set up underlying transport driver, with a pair of read and write ends.
    pub fn set_split_io<Reader, Writer>(
        &mut self,
        read: Reader,
        write: Writer,
    ) -> Result<&mut Self, Error>
    where
        Reader: 'static + AbstractReader,
        Writer: 'static + AbstractWriter,
    {
        let bio = RustBio::new_split(read, write)?;
        unsafe {
            // Safety: the additional ref-count is to compensate for `SSL` taking ownership.
            bssl_sys::BIO_up_ref(bio.ptr());
            // Safety: the `bio` pointer has been sanitised and `self.0` is still valid.
            bssl_sys::SSL_set_bio(self.ptr(), bio.ptr(), bio.ptr());
        }
        self.get_connection_methods().bio = Some(bio);
        Ok(self)
    }

    /// **For DTLS only**, trigger timeout handling on the connection.
    ///
    /// On success, this method call returns `true` when a timeout is hit and successfully handled;
    /// `false` when no timeout has expired yet.
    pub fn dtlsv1_handle_timeout(&mut self) -> Result<bool, Error> {
        let conn = self.ptr();
        let rc = unsafe {
            // Safety: the connection handle here is still valid.
            bssl_sys::DTLSv1_handle_timeout(conn)
        };
        if rc == 0 {
            return Ok(false);
        }
        let _ = check_tls_error!(conn, rc);
        Ok(true)
    }

    /// **For DTLS only**, get connection's remaining timeout.
    ///
    /// If a timeout is in effect, this method call returns the remaining seconds,
    /// followed by the remaining microseconds.
    pub fn dtlsv1_get_timeout(&self) -> Option<(i64, i64)> {
        #[cfg(windows)]
        #[repr(C)]
        struct timeval {
            tv_sec: core::ffi::c_long,
            tv_usec: core::ffi::c_long,
        }
        #[cfg(not(windows))]
        use bssl_sys::timeval;

        let mut timeval = MaybeUninit::<timeval>::zeroed();
        let rc = unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`;
            // - the buffer for timeval is valid.
            // - on Windows, the timeval structure should match the winsock2.h definition precisely.
            bssl_sys::DTLSv1_get_timeout(self.ptr(), transmute(timeval.as_mut_ptr()))
        };
        match rc {
            1 => {
                let timeval = unsafe {
                    // Safety: timeval is now valid as per BoringSSL specification.
                    timeval.assume_init()
                };
                Some((timeval.tv_sec as i64, timeval.tv_usec as i64))
            }
            0 => None,
            rc => {
                unreachable!("BoringSSL should never return {rc} when calling dtlsv1_get_timeout")
            }
        }
    }

    /// Check if the underlying **transport** has closed its write end.
    pub fn is_write_closed(&self) -> bool {
        self.get_connection_methods_ref()
            .bio
            .as_ref()
            .map_or(true, |bio| bio.as_ref().write_eos)
    }

    /// Check if the underlying **transport** has closed its read end.
    pub fn is_read_closed(&self) -> bool {
        self.get_connection_methods_ref()
            .bio
            .as_ref()
            .map_or(true, |bio| bio.as_ref().read_eos)
    }

    /// Check if the underlying **transport** has closed either its read end or its write end.
    pub fn is_one_side_closed(&self) -> bool {
        self.get_connection_methods_ref()
            .bio
            .as_ref()
            .map_or(true, |bio| bio.as_ref().read_eos || bio.as_ref().write_eos)
    }
}

/// # Transport configurations
///
/// These are the methods to configure the underlying IO drivers and transport configurations.
impl<R, M> TlsConnectionBuilder<R, M>
where
    M: HasTlsConnectionMethod,
{
    /// **For DTLS only**, set connection's Maximum Transmission Unit.
    pub fn with_mtu(&mut self, mtu: u32) -> Result<&mut Self, Error> {
        let conn = self.ptr();
        let mtu = mtu
            .try_into()
            .map_err(|_| Error::Configuration(ConfigurationError::InvalidParameters))?;
        check_lib_error!(unsafe {
            // Safety: `conn` is still valid.
            bssl_sys::SSL_set_mtu(conn, mtu)
        });
        Ok(self)
    }

    /// **For DTLS only**, set connection's handshake timeout in milliseconds.
    pub fn with_dtlsv1_initial_timeout(&mut self, milliseconds: u32) -> Result<&mut Self, Error> {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::DTLSv1_set_initial_timeout_duration(self.ptr(), milliseconds);
        }
        Ok(self)
    }
}
