 /********************************************************************************
 * Copyright (c) 2025-2026 ZF Friedrichshafen AG
 *
 * This program and the accompanying materials are made available under the 
 * terms of the Apache License Version 2.0 which is available at
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * SPDX-License-Identifier: Apache-2.0 
 *
 * Contributors:
 *   Erik Verhoeven - initial API and implementation
 ********************************************************************************/

#include "core.idl"

/**
 * @brief Software Defined Vehicle framework.
 */
module sdv
{
    /**
     * @brief Interprocess communication features.
     */
    module ipc
    {
        /**
         * @brief structure of IPC Connection to which a client can attach.
         */
        struct SChannelEndpoint
        {
            IInterfaceAccess  pConnection;      ///< Connection object
            u8string          ssConnectString;  ///< Parameter string used by other participant to establish a connection. The
                                                ///< parameter string is a TOMl description containing the identification of the
                                                ///< provider among with provider specific connection details. The provider
                                                ///< identification must be similar to the following example:
                                                ///< @code
                                                ///< [Provider]
                                                ///< Name = "DefaultSharedMemory"
                                                ///< @endcode
        };

        /**
         * @brief Interface for creating an IPC connection, which other participants can connect to via IChannelAccess.
         * @attention The channel control object should allow the creation of channels with a fixed configuration (e.g. a provided
         * name or a port), which is necessary for the creation of a listener. It also should allow dynamic channel creation (e.g.
         * automatic name or port-number) to create additional connections between components.
         */
        interface ICreateEndpoint
        {
            /**
             * @brief Create IPC connection object and return the endpoint information.
             * @post Use AsyncConnect on SChannelEndpoint::pConnection to initiate the connection.
             * @param[in] ssChannelConfig Optional channel type specific endpoint configuration. The configuration is a TOML base
             * description specific to the provider.
             * @return IPC connection object
             */
            SChannelEndpoint CreateEndpoint(in u8string ssChannelConfig);
        };

        /**
         * @brief Interface local IPC access.
         */
        interface IChannelAccess
        {
            /**
             * @brief Create a connection object from the channel connection parameters string.
             * @post Use AsyncConnect to initiate the connection.
             * @param[in] ssConnectString Reference to the string containing the channel connection parameters returned by the
             * ICreateEndpoint::CreateEndpoint function or a TOML configuration that is provider specific and describes clearly the
             * access to a running channel. This configuration is identical (or similar) to the configuration supplied to the
             * ICreateEndpoint::CreateEndpoint function.
             * @return Pointer to IInterfaceAccess interface of the connection object or NULL when the object cannot be created.
             */
            IInterfaceAccess Access(in u8string ssConnectString);
        };

        /**
         * @brief Connection state enumeration
         */
        enum EConnectState : uint32
        {
            uninitialized = 0,              ///< Initialization via IConnect pending/required
            initializing = 1,               ///< Initiation channel access.
            initialized = 2,                ///< Channel access initialized.
            connecting = 10,                ///< Both participants are available, connecting started
            negotiating = 20,               ///< Negotiating the connection
            connection_error = 990,         ///< Connection error; negotiation failed
            connected = 11,                 ///< Connection successful
            communication_error = 991,      ///< Communication error
            disconnected = 30,              ///< Connection terminated due to disconnection of other participant
            disconnected_forced = 32,       ///< Connection terminated due to unplanned disconnection of other participant
            terminating = 90,               ///< Termination of channel access (through IObjectDestroy::DestroyObject)
        };

        /**
         * @brief Interface for managing IPC connection.
         */
        interface IConnect
        {
            /**
             * @brief Establish a connection and start sending/receiving messages.
             * @param[in] pReceiver Callback interface for receiving data and connect state.
             * @return Returns 'true' when a channel connection could be initiated. Use GetConnectState or IConnectEventCallback to
             * check the connection state.
             */
            boolean AsyncConnect(in IInterfaceAccess pReceiver);

            /**
             * @brief Wait for a connection to take place.
             * @param[in] uiWaitMs Wait for a connection to take place. A value of 0 doesn't wait at all, a value of 0xffffffff
             * waits for infinite time.
             * @return Returns 'true' when a connection took place.
             */
            boolean WaitForConnection(in uint32 uiWaitMs);

            /**
             * @brief Cancel a wait for connection.
             */
            void CancelWait();

            /**
             * @brief Disconnect from a connection. This will set the connect state to disconnected and release the interface
             * used for the state events.
             */
            void Disconnect();

            /**
             * @brief Register event callback interface.
             * @details Register a connection state event callback interface. The exposed interface must be of type
             * IConnectEventCallback. The registration will exist until a call to the unregister function with the returned cookie
             * or until the connection is terminated.
             * @param[in] pEventCallback Pointer to the object exposing the IConnectEventCallback interface.
             * @return The cookie assigned to the registration or 0 when the registration wasn't successful.
            */
            uint64 RegisterStateEventCallback(in IInterfaceAccess pEventCallback);

            /**
             * @brief Unregister the state event callback with the returned cookie from the registration.
             * @param[in] uiCookie The cookie returned by a previous call to the registration function.
             */
            void UnregisterStateEventCallback(in uint64 uiCookie);

            /**
             * @brief Get the current state of the IPC connection.
             * @return Returns connection state.
             */
            EConnectState GetConnectState() const;
        };

        /**
         * @brief Interface implemented by the connecting object to receive channel connection events.
         */
        interface IConnectEventCallback
        {
            /**
             * @brief Set the current connect state.
             * @param[in] eConnectState The connection state.
            */
            void SetConnectState(in EConnectState eConnectState);
        };

        /**
         * @brief Interface implemented by the channel connection object for sending messages through a channel.
         */
        interface IDataSend
        {
            /**
             * @brief Sends data consisting of multiple data chunks via the IPC connection.
             * @param[inout] seqData Sequence of data buffers to be sent. The sequence might be changed to optimize the
             * communication without having to copy the data.
             * @return Return 'true' if all data could be sent; 'false' otherwise.
             */
            boolean SendData(inout sequence<pointer<uint8>> seqData);
        };

        /**
         * @brief Interface implemented by the connecting object that allows receiving messages.
         */
        interface IDataReceiveCallback
        {
            /**
             * @brief Callback to be called by the IPC connection when receiving a data packet.
             * @param[inout] seqData Sequence of data buffers to received. The sequence might be changed to optimize the
             * communication without having to copy the data.
             */
            void ReceiveData(inout sequence<pointer<uint8>> seqData);
        };
    }; // module ipc
}; // module sdv
