// 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 lifecycle controls

use alloc::boxed::Box;
use core::{
    future::poll_fn,
    ops::{Deref, DerefMut},
    task::Poll,
};

use crate::{
    check_tls_error,
    connection::{Client, Server, TlsConnectionRef, methods::HasTlsConnectionMethod},
    context::{SupportedMode, TlsMode},
    errors::{Error, TlsErrorReason, TlsRetryReason},
    io::IoStatus,
};

/// # Connection shutdown
impl<R, M> TlsConnectionRef<R, M> {
    /// Set whether shutting down this connection sends out a `close_notify` alert.
    pub fn set_quiet_shutdown(&mut self, quiet: bool) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_set_quiet_shutdown(self.ptr(), if quiet { 1 } else { 0 });
        }
        self
    }

    /// Check whether shutting down this connection sends out a `close_notify` alert.
    pub fn get_quiet_shutdown(&self) -> bool {
        let rc = unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_get_quiet_shutdown(self.ptr())
        };
        rc == 1
    }
}

/// # Connection initialisation state
///
/// There are methods and accessors that become available only when the connection is in the right
/// state.
///
/// Please refer to [`EstablishedTlsConnection`] and [`TlsConnectionInHandshake`] for allowed
/// operations.
impl<R, M> TlsConnectionRef<R, M> {
    /// Access handshake-related options if the connection is in handshake mode.
    pub fn in_handshake<'a>(&'a mut self) -> Option<TlsConnectionInHandshake<'a, R, M>> {
        if self.is_in_handshake() {
            Some(TlsConnectionInHandshake(self))
        } else {
            None
        }
    }

    /// Access handshake-related options if a handshake is completed and
    /// the connection is initialised.
    pub fn established<'a>(&'a mut self) -> Option<EstablishedTlsConnection<'a, R, M>> {
        let session = unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_get_session(self.ptr())
        };
        if session.is_null() {
            return None;
        }
        Some(EstablishedTlsConnection(self))
    }
}

bssl_macros::bssl_enum! {
    /// TLS data-pending reasons
    pub enum TlsPendingData: i32 {
        /// TLS connection wants to read more data.
        WantRead = bssl_sys::SSL_READING as i32,
        /// TLS connection wants to write more data.
        WantWrite = bssl_sys::SSL_WRITING as i32,
    }
}

/// # Connection state
///
/// When operations on [`TlsConnectionRef`] return with pending status,
/// there will be reasons why the operations should be retried.
impl<R, M> TlsConnectionRef<R, M> {
    /// Check the connection if it needs additional data.
    pub fn wants_data(&self) -> Option<TlsPendingData> {
        let code = unsafe {
            // Safety: the validity of the handle is witnessed by `self`.
            bssl_sys::SSL_want(self.ptr())
        };
        let code = i32::try_from(code).ok()?;
        TlsPendingData::try_from(code).ok()
    }
}

impl<R> TlsConnectionRef<R, TlsMode> {
    /// Inspect if the connection is suspended for which reason, after invocation of I/O methods.
    pub fn take_pending_reason(&mut self) -> Option<TlsRetryReason> {
        let methods = self.get_connection_methods();
        methods.take_pending_reason()
    }
}

/// A handle to the connection that is valid only during handshake.
#[repr(transparent)]
pub struct TlsConnectionInHandshake<'a, R, M>(pub(crate) &'a mut TlsConnectionRef<R, M>);

impl<R, M> Deref for TlsConnectionInHandshake<'_, R, M> {
    type Target = TlsConnectionRef<R, M>;
    fn deref(&self) -> &Self::Target {
        &*self.0
    }
}

impl<R, M> DerefMut for TlsConnectionInHandshake<'_, R, M> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.0
    }
}

impl<R, M> TlsConnectionInHandshake<'_, R, M>
where
    M: HasTlsConnectionMethod,
{
    #[allow(unused)] // This method will be used in the following patch to support some async tasks.
    pub(super) fn get_connection_methods(
        &mut self,
    ) -> &mut super::methods::RustConnectionMethods<M> {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            super::get_connection_methods(self.ptr())
        }
    }
}

/// # Handshake
impl<R, M> TlsConnectionInHandshake<'_, R, M>
where
    M: HasTlsConnectionMethod,
{
    /// Continue the handshake.
    ///
    /// Call this method after the initial [`Self::accept`] or [`Self::connect`],
    /// should the handshake be suspended.
    pub fn do_handshake(&mut self) -> Result<&mut Self, Error> {
        let conn = self.ptr();
        check_tls_error!(conn, bssl_sys::SSL_do_handshake(conn));
        Ok(self)
    }
}

impl<M> TlsConnectionInHandshake<'_, Server, M>
where
    M: HasTlsConnectionMethod,
{
    /// Accept a connection by responding to `ClientHello` with `ServerHello`.
    pub fn accept(&mut self) -> Result<&mut Self, Error> {
        let conn = self.ptr();
        check_tls_error!(conn, bssl_sys::SSL_accept(conn));
        Ok(self)
    }
}

impl<M> TlsConnectionInHandshake<'_, Client, M>
where
    M: HasTlsConnectionMethod,
{
    /// Initiate a connection by sending a `ClientHello`.
    pub fn connect(&mut self) -> Result<&mut Self, Error> {
        let conn = self.ptr();
        check_tls_error!(conn, bssl_sys::SSL_connect(conn));
        Ok(self)
    }
}

/// A handle to the connection that is valid only after initialization, or in other words after
/// handshake.
#[repr(transparent)]
pub struct EstablishedTlsConnection<'a, R, M = TlsMode>(&'a mut TlsConnectionRef<R, M>);

impl<R, M> Deref for EstablishedTlsConnection<'_, R, M> {
    type Target = TlsConnectionRef<R, M>;
    fn deref(&self) -> &Self::Target {
        &*self.0
    }
}

impl<R, M> DerefMut for EstablishedTlsConnection<'_, R, M> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.0
    }
}

impl<R> EstablishedTlsConnection<'_, R, TlsMode> {
    /// Perform synchronising shutdown.
    ///
    /// # Shutdown protocol
    /// A live connection can be actively shut down by calling this method at most two times.
    /// The first call will send `close_notify` down the transport.
    /// On `Ok` the first call is considered successful with the following return value.
    /// - [`ShutdownStatus::CloseNotifyReceived`] signifies that a `close_notify` is received from the peer, too.
    /// - [`ShutdownStatus::CloseNotifyPosted`] signifies that a `close_notify` from our end is sent but that from the peer
    ///   has not arrived.
    ///
    /// In case of no reception of peer `close_notify`, it is necessary to call this method again.
    /// There are two possible outcomes.
    /// - [`ShutdownStatus::RemainingApplicationData`] signifies that there are pending application data.
    ///   Process it until the stream ends.
    /// - [`ShutdownStatus::CloseNotifyReceived`] signifies that a `close_notify` is received from the peer, too.
    ///   The connection is then in terminal state.
    /// To process the remaining application data, normal reading should continue until the end of
    /// stream, at which [`Self::sync_shutdown`] can be called again to set the connection to the terminal state.
    pub fn sync_shutdown(&mut self) -> Result<ShutdownStatus, Error> {
        let rc = unsafe {
            // Safety: we have exclusive access to the connection state.
            bssl_sys::SSL_shutdown(self.ptr())
        };
        if self.is_write_closed() {
            return Ok(ShutdownStatus::CloseNotifyReceived);
        }
        match rc {
            0 => Ok(ShutdownStatus::CloseNotifyPosted),
            1 => Ok(ShutdownStatus::CloseNotifyReceived),
            _ => match self.categorise_error_for_io(rc) {
                Ok(IoStatus::Ok(_)) => unreachable!(),
                Ok(IoStatus::Empty | IoStatus::EndOfStream) => {
                    Err(Error::Io(crate::errors::IoError::EndOfStream))
                }
                Ok(IoStatus::Retry(reason)) => Err(Error::TlsRetry(reason)),
                Err(Error::TlsReason(TlsErrorReason::ApplicationDataOnShutdown)) => {
                    Ok(ShutdownStatus::RemainingApplicationData)
                }
                Err(Error::Library(0, _, _)) => Ok(ShutdownStatus::CloseNotifyReceived),
                Ok(IoStatus::Err) => Err(Error::Unknown(Box::new("transport error".to_string()))),
                Err(e) => Err(e),
            },
        }
    }
}

impl<R, M> TlsConnectionInHandshake<'_, R, M>
where
    M: SupportedMode,
{
    /// Perform asynchronous handshake, until completion or until pending on non-I/O operations.
    ///
    /// The caller needs to ensure that any pending operations during the handshake are resolved.
    pub fn async_handshake(&mut self) -> impl Send + Future<Output = Result<(), Error>> + '_ {
        poll_fn(move |cx| {
            self.set_waker(cx.waker());
            match self.do_handshake() {
                Ok(_) => Poll::Ready(Ok(())),
                Err(Error::TlsRetry(r)) => {
                    if matches!(r, TlsRetryReason::WantRead | TlsRetryReason::WantWrite) {
                        Poll::Pending
                    } else {
                        Poll::Ready(Err(Error::TlsRetry(r)))
                    }
                }
                Err(e) => Poll::Ready(Err(e)),
            }
        })
    }
}

/// Shutdown progress
pub enum ShutdownStatus {
    /// `close_notify` has been sent.
    CloseNotifyPosted,
    /// Peer `close_notify` has been received. The connection is now in terminal state.
    CloseNotifyReceived,
    /// There are remaining application data. Consume them first before calling `shutdown` again.
    RemainingApplicationData,
}
