// 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,
    string::ToString, //
};
use core::{
    future::poll_fn,
    ops::{
        Deref,
        DerefMut, //
    },
    task::Poll, //
};

use crate::{
    alerts::AlertDescription,
    check_tls_error,
    connection::{
        Client,
        Server,
        TlsConnection,
        methods::HasTlsConnectionMethod, //
    },
    context::{
        HasBasicIo,
        SupportedMode,
        TlsMode, //
    },
    errors::{
        Error,
        TlsErrorReason,
        TlsRetryReason, //
    },
    io::IoStatus, //
};

/// # Connection shutdown
impl<R, M> TlsConnection<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> TlsConnection<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>> {
        (!self.is_in_handshake()).then_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 [`TlsConnection`] return with pending status,
/// there will be reasons why the operations should be retried.
impl<R, M> TlsConnection<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()
    }
}

/// # Alerts
impl<R, M> TlsConnection<R, M>
where
    M: HasTlsConnectionMethod,
{
    /// Send fatal alert.
    ///
    /// This would usually lead to termination of the connection.
    pub fn send_fatal_alert(
        &mut self,
        alert: AlertDescription,
    ) -> Result<Option<TlsRetryReason>, Error> {
        Ok(check_tls_error!(self.ptr(), {
            // Safety: `self.0` is still a valid handle and `alert` is valid by construction.
            bssl_sys::SSL_send_fatal_alert(self.ptr(), alert as u8)
        }))
    }

    /// Send fatal alert asynchronously.
    pub fn async_send_fatal_alert<'a>(
        &'a mut self,
        alert: AlertDescription,
    ) -> impl 'a + Send + Future<Output = Result<(), Error>> {
        poll_fn(move |cx| {
            self.set_waker(cx.waker());
            match self.send_fatal_alert(alert) {
                Ok(Some(TlsRetryReason::WantRead | TlsRetryReason::WantWrite)) => Poll::Pending,
                Ok(None) => Poll::Ready(Ok(())),
                Ok(Some(reason)) => unreachable!("unexpected retry reason {reason:?}"),
                Err(e) => Poll::Ready(Err(e)),
            }
        })
    }
}

impl<R> TlsConnection<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> {
        self.get_connection_methods().take_pending_reason()
    }
}

/// A handle to the connection that is valid only during handshake.
// NOTE(@xfding): this type is strictly for configuration of the connection during the handshake,
// and no methods should be allowed to drive the TLS state machine.
#[repr(transparent)]
pub struct TlsConnectionInHandshake<'a, R, M>(pub(crate) &'a mut TlsConnection<R, M>);

/// # Handshake
impl<R, M> TlsConnection<R, M>
where
    M: HasTlsConnectionMethod,
{
    /// Drive the handshake.
    ///
    /// Call this method after the initial [`Self::accept`] or [`Self::connect`],
    /// should the handshake be suspended.
    ///
    /// This method returns `Ok(None)` to signal handshake completion;
    /// otherwise, `Ok(Some(reason))` is returned and the suspension `reason` must be resolved first
    /// before this method can make progress again.
    pub fn do_handshake(&mut self) -> Result<Option<TlsRetryReason>, Error> {
        let conn = self.ptr();
        Ok(check_tls_error!(conn, bssl_sys::SSL_do_handshake(conn)))
    }
}

impl<M> TlsConnection<Server, M>
where
    M: HasTlsConnectionMethod,
{
    /// Accept a connection by responding to `ClientHello` with `ServerHello`.
    ///
    /// This method returns `Ok(None)` to signal handshake completion;
    /// otherwise, given `Ok(Some(reason))` the suspension `reason` must be resolved first
    /// before calling [`Self::do_handshake`] can make progress again.
    pub fn accept(&mut self) -> Result<Option<TlsRetryReason>, Error> {
        self.do_handshake()
    }
}

impl<M> TlsConnection<Client, M>
where
    M: HasTlsConnectionMethod,
{
    /// Initiate a connection by sending a `ClientHello`.
    ///
    /// This method returns `Ok(None)` to signal handshake completion;
    /// otherwise, given `Ok(Some(reason))` the suspension `reason` must be resolved first
    /// before calling [`Self::do_handshake`] can make progress again.
    pub fn connect(&mut self) -> Result<Option<TlsRetryReason>, Error> {
        self.do_handshake()
    }
}

/// 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 TlsConnection<R, M>);

impl<R, M> Deref for EstablishedTlsConnection<'_, R, M> {
    type Target = TlsConnection<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, M> EstablishedTlsConnection<'_, R, M>
where
    M: HasTlsConnectionMethod + HasBasicIo,
{
    /// Perform synchronising shutdown.
    ///
    /// If the method returns `Ok(None)`, the shutdown will not progress until I/O makes progress.
    ///
    /// # 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<Option<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(Some(ShutdownStatus::EndOfStream));
        }
        match rc {
            0 => Ok(Some(ShutdownStatus::CloseNotifyPosted)),
            1 => Ok(Some(ShutdownStatus::CloseNotifyReceived)),
            _ => match self.categorise_error_for_io(rc) {
                Ok(IoStatus::Ok(_)) => unreachable!(),
                Ok(IoStatus::Empty | IoStatus::EndOfStream) => {
                    Ok(Some(ShutdownStatus::EndOfStream))
                }
                Ok(IoStatus::Retry(TlsRetryReason::WantRead | TlsRetryReason::WantWrite)) => {
                    Ok(None)
                }
                Ok(IoStatus::Retry(reason)) => panic!("unexpected retry reason {reason:?}"),
                Err(Error::TlsReason(TlsErrorReason::ApplicationDataOnShutdown)) => {
                    Ok(Some(ShutdownStatus::RemainingApplicationData))
                }
                Err(Error::Library(0, _, _)) => Ok(Some(ShutdownStatus::CloseNotifyReceived)),
                Ok(IoStatus::Err) => Err(Error::Unknown(Box::new("transport error".to_string()))),
                Err(e) => Err(e),
            },
        }
    }
}

impl<R, M> TlsConnection<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,
    /// before polling [`Self::async_handshake`] again.
    pub fn async_handshake(
        &mut self,
    ) -> impl Send + Future<Output = Result<Option<TlsRetryReason>, Error>> + '_ {
        poll_fn(move |cx| {
            self.set_waker(cx.waker());
            match self.do_handshake() {
                Ok(Some(TlsRetryReason::WantRead | TlsRetryReason::WantWrite)) => Poll::Pending,
                Ok(Some(reason)) => Poll::Ready(Ok(Some(reason))),
                Ok(None) => Poll::Ready(Ok(None)),
                Err(e) => Poll::Ready(Err(e)),
            }
        })
    }

    /// Perform asynchronous handshake, until completion, knowing that all possible pending reasons
    /// will resolve themselves.
    ///
    /// The caller needs to ensure that any pending operations due to asynchronous operations such as
    /// certificate verification and private key operations will eventually resolve and wake up
    /// the handshake task.
    /// Otherwise the handshake task will never complete.
    pub fn async_nonstop_handshake(
        &mut self,
    ) -> impl Send + Future<Output = Result<(), Error>> + '_ {
        poll_fn(move |cx| {
            self.set_waker(cx.waker());
            match self.do_handshake() {
                Ok(Some(_)) => Poll::Pending,
                Ok(None) => Poll::Ready(Ok(())),
                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,
    /// The read half of the connection reaches the end of the stream.
    EndOfStream,
}
