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

#include <Event.idl>

/**
 * Device Date and Time Configuration
 */
module datetime {

    /** Date and time configuration methods
     *
     *  Example to set timezone (id-based approach): @anchor set-timezone-example
     *
     * @code{.py}
     * zoneinfos = getZoneInfos(False)
     * cfg = getCfg()
     * cfg.zoneCfg.id = ... # choose zone id from returned zoneinfos
     * status = setCfg(cfg)
     * if status != 0: ... # error handling
     * @endcode
     */
    interface DateTime_3_0_3 {

        /** Time zone information (see also ZoneCfg)
         *
         * There are two different approaches on how to identify timezones. See the ZoneCfg description.
         *
         * For timezones with non-trivial daylight saving time rules #hasDSTInfo is \c false.
         */
        structure ZoneInfo {
            int    id;                  ///< Time zone id
            string name;                ///< Time zone name
            boolean hasDSTInfo;         ///< \c true if the time zone has daylight saving time rules
        };

        /** Time zone configuration
         *
         *  There are two approaches on how timezones are identified:
         *  1. id-based
         *
         *     - timezone data identified with a numeric non-zero id
         *     - #id != 0
         *     - #name is the display name of the timezone and ignored on setCfg()
         *
         *  2. name-based (see NOTES below!)
         *
         *     - timezone data identified with a name from the IANA timezone database (aka Olson database)
         *     - #id == 0
         *     - #name is the official IANA timezone name, e.g. Europe/Berlin or America/New_York
         *
         *  **NOTES**:
         *  - The user frontends currently only support the id-based approach and may not work correctly with
         *    the name-based approach.
         *  - Setting #enableAutoDST to \c true has only an effect if the according ZoneInfo::hasDSTInfo
         *    field is also \c true.
         */
        structure ZoneCfg {
            int id;                     ///< Selected time zone id
            string name;                ///< Selected time zone name (ignored on setCfg() if id != 0)
            boolean enableAutoDST;      ///< Enable automatic daylight saving time adjustment
        };

        /** Time synchronization protocol */
        enumeration Protocol {
            STATIC,                     ///< Device time is configured locally
            NTP                         ///< Device time is synchronized via NTP
        };

        /** Static NTP server configuration */
        structure NtpCfg {
            string server1;             ///< Primary NTP server
            string server2;             ///< Secondary NTP server
        };

        /** Device date and time configuration */
        structure Cfg {
            ZoneCfg zoneCfg;            ///< Time zone configuration
            Protocol protocol;          ///< Time synchronization protocol
            time deviceTime;            ///< Device date and time (local time)
            NtpCfg ntpCfg;              ///< NTP server configuration
        };

        /** Event that is sent when the configuration changes */
        valueobject ConfigurationChangedEvent extends idl.Event {
        };

        /** Event that is sent when the device time is changed */
        valueobject ClockChangedEvent extends idl.Event {
            time oldTime;               ///< Device time before change (UNIX timestamp, UTC)
            time newTime;               ///< Device time after change (UNIX timestamp, UTC)
        };

        /**
         * List all supported time zones.
         *
         * @param zoneInfos  Result: List of time zones
         * @param useOlson   Use Olson timezone names (see also ZoneCfg)
         */
        void getZoneInfos(out vector<ZoneInfo> zoneInfos, in boolean useOlson);

        /**
         * Check if a specified NTP server is usable.
         *
         * @param ntpServer  NTP server to be checked
         *
         * @return \c true if the NTP server is usable
         */
        boolean checkNtpServer(in string ntpServer);

        /**
         * Get active NTP servers.
         *
         * @return List of currently active NTP servers (IP addresses and/or hostnames)
         */
        vector<string> getActiveNtpServers();

        /**
         * Retrieve the device date and time configuration.
         *
         * @param cfg  Result: Current date and time configration
         */
        void getCfg(out Cfg cfg);

        /**
         * Set the device date and time configuration.
         * Depending on the value of the \e protocol field either \e deviceTime
         * or \e ntpCfg will be used from the \e cfg parameter.
         *
         * Specific @ref set-timezone-example "example" to set timezone.
         *
         * @param cfg  New date and time configuration.
         *
         * @return 0 if OK
         * @return 1 if the configuration is invalid
         */
        int setCfg(in Cfg cfg);

        /**
         * Retrieve the current device date and time.
         *
         * @param useOlson     Use Olson timezone name (see also ZoneCfg)
         * @param zone         Result: Active time zone
         * @param dstEnabled   if false, the time zone daylight saving time flag is not used
         * @param utcOffset    Result: Offset (in minutes) between local time and UTC
         * @param currentTime  Result: Device date and time (UNIX timestamp, UTC)
         */
        void getTime(in boolean useOlson, out ZoneInfo zone,
                     out boolean dstEnabled, out int utcOffset,
                     out time currentTime);

    };

}
