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

#include <Event.idl>

/**
 * Port-forwarding auto-setup
 */
module net {

    /** The state of a specific expansion unit during a port-forwarding auto-setup run */
    enumeration PortForwardingAutoSetupExpansionUnitState {
        PF_AUTO_SETUP_UNIT_ALREADY_EXISTS,                          ///< Expansion unit already exists, no further setup needed
        PF_AUTO_SETUP_UNIT_PENDING,                                 ///< Currently trying to discover and setup this unit
        PF_AUTO_SETUP_UNIT_ADDED,                                   ///< Expansion unit was successfully added
        PF_AUTO_SETUP_UNIT_ERROR                                    ///< Could not add this expansion unit
    };

    structure PortForwardingAutoSetupExpansionUnit {
        PortForwardingAutoSetupExpansionUnitState state;            ///< The state of this unit in this auto-setup
        string errMsg;                                              ///< If state is \c PF_AUTO_SETUP_UNIT_ERROR this describes the error
    };

    /** The state of a port-forwarding auto-setup run */
    enumeration PortForwardingAutoSetupRunningState {
        PF_AUTO_SETUP_NONE,                                         ///< No port-forwarding auto-setup run available
        PF_AUTO_SETUP_RUNNING,                                      ///< Port-forwarding auto-setup is currently running
        PF_AUTO_SETUP_CANCELED,                                     ///< Port-forwarding auto-setup was canceled
        PF_AUTO_SETUP_FINISHED_WITH_ERROR,                          ///< Port-forwarding auto-setup finished with an error
        PF_AUTO_SETUP_FINISHED_SUCCESSFULLY                         ///< Port-forwarding auto-setup finished successfully
    };

    /** The status and expansion units of a port-forwarding auto-setup run */
    structure PortForwardingAutoSetupStatus {
        time startTime;                                                     ///< UNIX timestamp (UTC) when the auto-setup was started
        int remainingExpansionUnits;                                        ///< Number of expansion units that still need to be discovered
        PortForwardingAutoSetupRunningState runningState;                   ///< The state of the last available auto-setup run
        map<int, PortForwardingAutoSetupExpansionUnit> expansionUnits;      ///< Results per expansion unit, mapped by their node index
    };

    /** The status of the auto-setup changed */
    valueobject PortForwardingAutoSetupStatusChangedEvent extends idl.Event {
        PortForwardingAutoSetupStatus newStatus;                    ///< The new port-forwarding auto-setup status
    };

    /** Interface for running the port-forwarding auto-setup */
    interface PortForwardingAutoSetup {

        /** Success code */
        constant int SUCCESS                                    = 0;
        constant int ERR_PF_AUTO_SETUP_NOT_A_PRIMARY_UNIT       = 1;
        constant int ERR_PF_AUTO_SETUP_ALREADY_RUNNING          = 2;
        constant int ERR_PF_AUTO_SETUP_INVALID_PARAM            = 3;

        /**
         * Start the port-forwarding auto-setup. This will try to discover
         * units that are connected to a port-forwarding downstream interface
         * and configure them as port-forwarding expansion units, one-by-one.
         * The auto-setup will exit if any errors occured or the number of
         * expansion units to discover was reached.
         *
         * The auto-setup can only be started on port-forwarding primary units.
         * It does not work with the USB downstream interface (will return
         * ERR_PF_AUTO_SETUP_INVALID_PARAM).
         *
         * @param numberOfExpansionUnits    how many expansion units should this port-forwarding cascade have
         * @param username                  the username that is used to login to the expansion units
         * @param password                  the password to login to the expansion units
         * @param newPassword               set a new password if an expansion unit needs to change the default password
         * @param disableStrongPasswordReq  \c true to disable strong password requirements of the expansion unit
         *
         * @return 0 if OK
         * @return ERR_PF_AUTO_SETUP_NOT_A_PRIMARY_UNIT  this unit is not a port-forwarding primary unit
         * @return ERR_PF_AUTO_SETUP_ALREADY_RUNNING     an earlier run of the port-forwarding auto-setup is still running
         * @return ERR_PF_AUTO_SETUP_INVALID_PARAM       one of the parameters was invalid
         */
        int start(in int numberOfExpansionUnits, in string username,
                  in string password, in string newPassword, in boolean disableStrongPasswordReq);

        /**
         * Get the status of a port-forwarding auto-setup.
         *
         * @return the status
         */
        PortForwardingAutoSetupStatus getStatus();

        /**
         * Cancel a running port-forwarding auto-setup
         */
        void cancel();
    };

}
