 /********************************************************************************
 * 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"
#include "toml.idl"

/**
 * @brief Software Defined Vehicle framework.
 */
module sdv
{
    /**
    * @brief Core features.
    */
    module app
    {

        /**
         * @brief The application operation state.
         */
        enum EAppOperationState
        {
            not_started = 0,            ///< The application hasn't been started yet.
            starting = 1,               ///< The application is starting.
            started = 2,                ///< The application has started.
            initializing = 10,          ///< The application is initializing.
            initialized = 12,           ///< The application has initialized.
            configuring = 20,           ///< The application switched to configuration mode.
            running = 30,               ///< The application is running/switched to running mode.
            shutting_down = 90,         ///< The application is shutting down.
        };

        /**
         * @brief Event structure. Dependable on the event, can be derived to provide additional information.
         */
        struct SAppEvent
        {
            uint32      uiEventID;  ///< The event ID of the event
            uint32      uiInfo;     ///< Additional information that can be used during a call to the event and as answer from
                                    ///< the implemented event handler. The information depends on the event that is triggered.
        };

        const uint32 EVENT_OPERATION_STATE_CHANGED = 1;     ///< Information about the application operation state. The information
                                                            ///< section of the event structure contains the current operation mode
                                                            ///< represented by the EAppOperationMode enum. This event is
                                                            ///< informational only and will be called by the core library to
                                                            ///< inform the application.

        const uint32 EVENT_RUNNING_LOOP = 8;                ///< Triggered every 2ms to do idle operations during the running loop.

        /**
        * @brief Application event system. To be implemented by the application.
        */
        local interface IAppEvent
        {
            /**
             * @brief Process the event.
             * @param[inout] sEvent Event structure containing the information to process.
             */
            void ProcessEvent(inout SAppEvent sEvent);
        };

        /**
        * @brief Application context types.
        */
        enum EAppContext : uint32
        {
            no_context = 0,     ///< The core hasn't started yet. No context available.
            standalone = 10,    ///< Running as standalone application. No component isolation instantiated. Additional
                                ///< configurations can be loaded.
            external = 20,      ///< External application. Component isolation in client mode.
            isolated = 30,      ///< Isolated application. Component isolation in client mode.
            main = 100,         ///< Main application. Component isolation in server mode.
            essential = 5,      ///< Bare minimum configuration. Local services loaded only. Additional configurations can be
                                ///< loaded.
            maintenance = 80,   ///< Maintenance application. Component isolation in client mode. Access to maintenance interfaces
                                ///< only.
        };

        /**
         * @brief Application context interface.
         */
        local interface IAppContext
        {
            /**
             * @brief Return the application context.
             * @return The context mode.
             */
            EAppContext GetContextType() const;

            /**
             * @brief Return the core instance ID.
             * @return The instance ID.
             */
            uint32 GetInstanceID() const;
        };

        /**
         * @brief Local application control.
         */
        local interface IAppControl
        {
            /**
             * @brief Start the application.
             * @details The core will prepare for an application start based on the provided configuration. Per default, the
             * application will be in running mode after successful startup.
             * @param[in] ssConfig String containing the configuration to be used by the core during startup. This configuration
             * is optional. If not provided the application runs as standalone application without any RPC support.
             * @param[in] pEventHandler Pointer to the event handler receiving application events. For the handler to receive
             * events, the handler needs to expose the IAppEvent interface. This pointer is optionally and can be NULL.
             * @return Returns 'true' on successful start-up and 'false' on failed startup.
             */
            boolean Startup(in u8string ssConfig, in IInterfaceAccess pEventHandler)
                raises(XAccessDenied, toml::XTOMLParseException);

            /**
             * @brief Running loop until shutdown request is triggered.
             */
            void RunLoop() raises(XAccessDenied, XInvalidState);

            /**
             * @brief Initiate a shutdown of the application.
             * @details The objects will be called to shutdown allowing them to clean up and gracefully shutdown. If, for some
             * reason, the object cannot shut down (e.g. pointers are still in use or threads are not finalized), the object will
             * be kept alive and the application state will stay in shutting-down-state. In that case the exception is called. A
             * new call to the shutdown function using the force-flag might force a shutdown. Alternatively the application can
             * wait until the application state changes to not-started.
             * @remarks Application shutdown is only possible when all components are released.
             * @param[in] bForce When set, forces an application shutdown. This might result in loss of data and should only be
             * used as a last resort.
             */
            void Shutdown(in boolean bForce) raises(XAccessDenied, XInvalidState, XTimeout);
        };

        /**
         * @brief Application operation control.
         */
        interface IAppOperation
        {
            /**
             * @brief Get the current operation state. This information is also supplied through the event handler function.
             * @return Returns the operation state of the application.
             */
            EAppOperationState GetOperationState() const;

            /**
             * @brief Switch from running mode to the configuration mode.
             */
            void SetConfigMode() raises(XAccessDenied, XInvalidState);

            /**
             * @brief Switch from the configuration mode to the running mode.
             */
            void SetRunningMode() raises(XAccessDenied, XInvalidState);
        };

        /**
         * @brief Request a shutdown (only for server).
         */
        interface IAppShutdownRequest
        {
            /**
             * @brief Request a shutdown. The function will only place the request to shut down.
             */
            void RequestShutdown() raises(XAccessDenied, XInvalidState);
        };

        /**
         * @brief Load and save the application settings.
         * @remarks The interface is only available in maintenance mode.
         */
        interface IAppSettingsPersist
        {
            /**
             * @brief Load the application settings.
             * @remarks When there is no settings file, this is not an error. Default settings will be assumed.
             * @return Returns whether the loading was successful.
             */
            boolean LoadSettings();

            /**
             * @brief Save the application settings file (or create when not existing yet).
             * @return Returns whether the saving was successful.
             */
            boolean SaveSettings();
        };

        /**
         * @brief Application connections
         * @remarks The interface is only available in maintenance mode.
         */
        interface IAppConnections
        {
            /**
             * @brief Get a sequence with listener names.
             * @return Sequence with listener name strings.
             */
            sequence<u8string> GetListeners() const;

            /**
             * @brief Get the listener configuration.
             * @param[in] ssName Name of the listener.
             * @return String containing the listener configuration.
             */
            u8string GetListenerConfig(in u8string ssName) const;

            /**
             * @brief Add or update a listener configuration.
             * @param[in] ssName Name of the listener configuration.
             * @param[in] ssConfig The configuration string for the listener.
             * @return Returns whether the listener could be added.
             */
            boolean AddListenerConfig(in u8string ssName, in u8string ssConfig);

            /**
             * @brief Remove a listener configuration with the provided name.
             * @param[in] ssName Name of the listener configuration.
             * @return Returns whether the removal was successful.
             */
            boolean RemoveListenerConfig(in u8string ssName);

            /**
             * @brief Get a sequence with connection names.
             * @return Sequence with name strings.
             */
            sequence<u8string> GetConnections() const;

            /**
             * @brief Get the connection configuration.
             * @param[in] ssName Name of the connection.
             * @return String containing the connection configuration.
             */
            u8string GetConnectionConfig(in u8string ssName) const;
        
            /**
             * @brief Add or update a connection configuration.
             * @param[in] ssName Name of the connection configuration.
             * @param[in] ssConfig The configuration string for the connection.
             * @param[in] ssInsertBefore Reference to the string to connection to insert the the new connection before, or empty
             * when the the new connection should be placed at the end.
             * @return Returns whether the connection could be added (fails when the connection already exists).
             */
            boolean AddConnectionConfig(in u8string ssName, in u8string ssConfig, in u8string ssInsertBefore);

            /**
             * @brief Remove a connection configuration with the provided name.
             * @param[in] ssName Name of the connection configuration.
             * @return Returns whether the removal was successful.
             */
            boolean RemoveConnectionConfig(in u8string ssName);

            /**
             * @brief Return the number of retries to establish a connection.
             * @return Number of retries.
             */
            uint32 GetConnectRetries() const;
        };

    }; // module app
}; // module sdv
