/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright 2010 Raritan Inc. All rights reserved.
 */

#include <Event.idl>
#include <UserEvent.idl>

/** Server Monitor */
module servermon {

    /** Server Monitor Interface */
    interface ServerMonitor_2_0_1 {

        /**
         * Server Reachability State
         */
        enumeration ServerReachability {
            WAITING,                            ///< Waiting for reliable connection
            REACHABLE,                          ///< Server is up and running
            UNREACHABLE,                        ///< No response from server
            ERROR                               ///< Error pinging server (e.g. DNS lookup failure)
        };

        /**
         * Server Power Control State
         */
        enumeration ServerPowerState {
            UNKNOWN,                            ///< Power state currently not known
            ON,                                 ///< Server power target is on
            OFF,                                ///< Server power target is off
            SHUTTING_DOWN                       ///< Server is being manually shut down
        };

        /**
        * Server Power Control Result
        */
        enumeration ServerPowerControlResult {
            NO_ERROR,                           ///< No error, operation may still be in progress
            SHUTDOWN_CMD_FAILED,                ///< Error issuing the shutdown command to the server
            SWITCHING_OFF_FAILED,               ///< Switching the outlet or outlet group off failed
            SWITCHING_ON_FAILED,                ///< Switching the outlet or outlet group on failed
            POWER_CHECK_TIMEOUT                 ///< Checking if power is off timed out
        };

        /**
         * Methods of checking power state
         */
        enumeration ServerPowerCheckMethod {
            TIMER,                              ///< Server is assumed to be off after a time interval
            POWER_DROP                          ///< Server is off if power consumption dropped
        };

        /**
         * Settings for controlling and checking power state of the server
         */
        structure ServerPowerSettings {
            boolean enabled;                    ///< Power control for this server enabled
            Object target;                      ///< Target for power control, Outlet or OutletGroup
            ServerPowerCheckMethod powerCheck;  ///< Method to check server's power state
            double powerThreshold;              ///< Active power below this threshold means server is off (in Watt)
            int timeout;                        ///< Seconds the power check takes before it ends / times out
            string shutdownCmd;                 ///< Shutdown command to send to the server
            string username;                    ///< Login used to issue shutdown command to the server
            string password;                    ///< Password for the login, write-only, not set if empty
            int sshPort;                        ///< SSH port of the server
        };

        /**
         * Server Reachability Settings
         */
        [sparse_in]
        structure ServerSettings {
            string host;                        ///< Server hostname/IP address
            boolean enabled;                    ///< Pinging enabled
            int pingInterval;                   ///< Wait time after successful ping
            int retryInterval;                  ///< Wait time after unsuccessful ping
            int activationCount;                ///< Minimum number of successful pings to enable feature
            int failureCount;                   ///< Number of unsuccessful pings to consider server down
            int resumeDelay;                    ///< Wait time before resuming pinging
            int resumeCount;                    ///< Number of resumes before going back to WAITING state
            ServerPowerSettings powerSettings;  ///< Settings for controlling the power state of the server
        };

        /**
         * Server Reachability Status
         */
        structure ServerStatus {
            ServerPowerState powerState;                        ///< Power control state
            ServerPowerControlResult lastPowerControlResult;    ///< Last result of a power control operation
            ServerReachability reachable;                       ///< Reachability state
            time lastRequest;                                   ///< UNIX timestamp (UTC) of last request sent
            time lastResponse;                                  ///< UNIX timestamp (UTC) of last response received
            int requests;                                       ///< Number of requests sent
            int responses;                                      ///< Number of responses received
            int failures;                                       ///< Number of consecutive failed pings
            int resumes;                                        ///< Number of resumes
        };

        /**
         * Event: ServerPowerState has changed
         */
        valueobject ServerPowerStateEvent extends idl.Event {
            int id;                             ///< id of the server entry
            string host;                        ///< Server hostname/IP address
            ServerPowerState oldPowerState;     ///< Old power state
            ServerPowerState newPowerState;     ///< New power state
        };

        /**
         * Event: A power control operation was initiated
         */
        valueobject ServerPowerControlInitiatedEvent extends event.UserEvent {
            int id;                             ///< id of the server
            string host;                        ///< Server hostname/IP address
            boolean on;                         ///< True if server shall be switched on, false otherwise
        };

        /**
         * Event: A power control operation was completed
         */
        valueobject ServerPowerControlCompletedEvent extends idl.Event {
            int id;                             ///< id of the server
            string host;                        ///< Server hostname/IP address
            ServerPowerControlResult result;    ///< Result of the power control operation
        };

        /**
         * Event: Reachability status for a monitored server has changed or
         * server continues to be unreachable
         */
        valueobject ServerReachabilityEvent extends idl.Event {
            int id;                             ///< id of the server entry
            string host;                        ///< Server hostname/IP address
            ServerReachability reachable;       ///< Current Reachability state
        };

        /**
         * A new server entry was added
         */
        valueobject ServerAddedEvent extends event.UserEvent {
            int id;                             ///< id of the added server entry
            ServerSettings settings;            ///< Settings of the added server
        };

        /**
         * A server entry was changed
         */
        valueobject ServerSettingsChangedEvent extends event.UserEvent {
            int id;                             ///< id of the server entry
            ServerSettings oldSettings;         ///< Settings before change
            ServerSettings newSettings;         ///< Settings after change
        };

        /**
         * A server entry was deleted
         */
        valueobject ServerDeletedEvent extends event.UserEvent {
            int id;                             ///< id of the deleted server entry
        };

        /**
         * Server Entry
         */
        structure Server {
            ServerSettings settings;            ///< Server settings
            ServerStatus status;                ///< Server status
        };

        constant int ERR_NO_SUCH_ID             = 1; ///< No such ID
        constant int ERR_INVALID_SETTINGS       = 2; ///< Invalid settings
        constant int ERR_DUPLICATE_HOSTNAME     = 3; ///< Duplicate hostname
        constant int ERR_MAX_SERVERS_REACHED    = 4; ///< Maximum number of server entries

        /**
         * Add a new server entry.
         *
         * @param id        New entry id, automatically assigned
         * @param settings  New server settings
         *
         * @return 0 if OK
         * @return 2 if the settings are invalid
         * @return 3 if an entry for the given hostname exists
         * @return 4 if the maximum number of servers is reached
         *
         * @note The ServerSettings structure can be "sparse"; fields missing in
         *       the JSON representation will be set to default values.
         */
        int addServer(out int id, in ServerSettings settings);

        /**
         * Modify an existing server entry.
         *
         * @param id        Entry id
         * @param settings  New settings
         *
         * @return 0 if OK
         * @return 1 if the entry does not exist
         * @return 2 if the settings are invalid
         * @return 3 if an entry for the given hostname exists
         *
         * @note The ServerSettings structure can be "sparse"; fields missing in
         *       the JSON representation will remain unchanged.
         */
        int modifyServer(in int id, in ServerSettings settings);

        /**
         * Delete a server entry.
         *
         * @param id        Entry id
         *
         * @return 0 if OK
         * @return 1 if the entry does not exist
         */
        int deleteServer(in int id);

        /**
         * Retrieve a server entry (settings and status).
         *
         * @param server    Server settings and status
         * @param id        Entry id
         *
         * @return 0 if OK
         * @return 1 if the entry does not exist
         */
        int getServer(out Server server, in int id);

        /**
         * Retrieve a list of server entries (settings and status).
         *
         * @return Server list
         */
        map<int, Server> listServers();

        /**
         * Control the power state of the outlets the server uses.
         * Attempting to switch the power off will issue a graceful shutdown of
         * the server beforehand.
         *
         * @param id       Entry id
         * @param on       Switch power on if true, off if false
         *
         * @return 0 if OK
         * @return 1 if the entry does not exist
         * @return 2 if the settings are invalid
         */
        int powerControl(in int id, in boolean on);

    };

}
