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

#ifndef __ASSETMGRMODEL_ASSETSTRIP_IDL__
#define __ASSETMGRMODEL_ASSETSTRIP_IDL__

#include <AssetStripConfig.idl>
#include <UserEvent.idl>

/**
 * Asset Management Model
 */
module assetmgrmodel {
    /** Asset Management Strip interface */
    interface AssetStrip_2_0_6 {

        /**
         * Error codes
         */
        constant int NO_ERROR                   = 0; ///< Operation successful, no error
        constant int ERR_INVALID_PARAM          = 1; ///< Invalid parameter for an operation
        constant int ERR_NO_SUCH_OBJECT         = 2; ///< Requested object does not exist
        constant int ERR_NOT_SUPPORTED          = 3; ///< Requested operation is not supported
        constant int ERR_OPERATION_FAILED       = 4; ///< Operation did not succeed

        /**
         * Constants
         */
        constant int MAIN_STRIP_COLUMN          = 0;

        /** %AssetStrip state */
        enumeration State {
            DISCONNECTED,       ///< No strip connected
            FIRMWARE_UPDATE,    ///< Firmware update in progress on main strip
            UNSUPPORTED,        ///< Connected asset strip is unsupported
            AVAILABLE           ///< Asset strip is up and running normally
        };

        /**
         * Type of an asset tag connected to a rack unit
         */
        enumeration TagType {
            SINGLE,             ///< single asset tag connected to main strip or an extension
            EXTENSION,          ///< blade server extension, only possible on the main strip
            NONE                ///< no asset tag connected to main strip or an extension
        };

        /**
         * For composite asset strips CascadeState shows additional information
         * about the state of the complete cascade
         */
        enumeration CascadeState {
            CASCADE_ACTIVE,         ///< cascade is up and running
            CASCADE_FIRMWARE_UPDATE ///< a device in the cascade receives a firmware update
        };

        /**
         * Static (type, version) information for an %AssetStrip.
         */
        structure DeviceInfo {
            int deviceId;                       ///< Device type (indicated a certain hardware)
            int hardwareId;                     ///< Hardware ID, revision
            int protocolVersion;                ///< Protocol version the strip is supporting
            int bootVersion;                    ///< Bootcode software version
            int appVersion;                     ///< Application code software version
            boolean orientationSensAvailable;   ///< Indicates whether the strip has an orientation sensor
            boolean isCascadable;               ///< The asset strip type
            boolean rackUnitCountConfigurable;  ///< Rack unit count has to be configured, i.e. is not auto detected
        };

        /**
         * Dynamic (may change with a connected strip) information for an %AssetStrip.
         */
        structure StripInfo {
            int maxMainTagCount;        ///< Maximum number of tags supported on the main strip
            int maxBladeTagCount;       ///< Maximum number of tags supported on blade extensions
            int mainTagCount;           ///< Current number of tags on the main asset strip
            int bladeTagCount;          ///< Current number of tags on all blade extensions
            boolean bladeOverflow;      ///< Out of space for new blade extension tags, read-only
            int rackUnitCount;          ///< Rack unit count, i.e. number of tags connectable
            int componentCount;         ///< Number of components
            CascadeState cascadeState;  ///< State of the cascade (only for composite strips)
        };

        /**
         * Information for a single tag
         */
        structure TagInfo {
            int rackUnitNumber;    ///< The rack unit index this tag is connected to, range 0..rackUnitCount-1
            int slotNumber;        ///< Blade slot this tag is connected to, 0 is the main strip, >0 for blades
            string familyDesc;     ///< Tag family description, indicating different tag hardware
            string rawId;          ///< The asset tag ID (6 byte hexadecimal string 'AABBCCDDEEFF')
            boolean programmable;  ///< Is the asset tag ID programmable?
        };

        /**
         * Infos for a single rack unit
         *
         * In case no asset strip is connected, type defaults to single and size defaults to 1
         */
        structure RackUnitInfo {
            int rackUnitNumber;         ///< The rack unit index for the settings, range 0..rackUnitCount-1
            int rackUnitPosition;       ///< resulting rack unit position (display number)
            TagType type;               ///< type of the asset tag (single, extension, none or unknown)
            int size;                   ///< blade extension size (4,8,16), 1 for single tags or 0 if nothing connected
            AssetStripConfig_1_0_1.RackUnitSettings settings;   ///< settings for a single rack unit
            int assetStripCascadePosition;        ///< number of strip in cascade
            int rackUnitRelativePosition;         ///< relative position to strip
            int assetStripNumberOfRackUnits;      ///< number of rack units in strip that this rack unit belongs to
        };

        /** Event: Asset strip dynamic information has changed */
        valueobject StripInfoChangedEvent extends idl.Event {
            StripInfo oldInfo;                                  ///< Information before change
            StripInfo newInfo;                                  ///< Information after change
        };

        /** Event: Asset strip state has changed */
        valueobject StateChangedEvent extends idl.Event {
            State oldState;                                     ///< State before change
            State newState;                                     ///< State after change
            DeviceInfo deviceInfo;                              ///< Information about connected strip, only valid
                                                                ///< if newState is AVAILABLE
        };

        /** Event: A rack unit has changed */
        valueobject RackUnitChangedEvent extends event.UserEvent {
            int rackUnitNumber;                                 ///< Affected rack unit index
            RackUnitInfo rackUnit;                              ///< New rack unit information
        };

        /**
         * Information describing a tag change
         */
        structure TagChangeInfo {
            TagInfo tag;                                        ///< Tag which was attached or detached
            RackUnitInfo info;                                  ///< Rack unit the tag was/is connected to
            string parentBladeTagId;                            ///< Asset tag ID of the parent blade tag,
                                                                ///< empty if the tag is not an extension tag
            int slotPosition;                                   ///< Blade slot position of the tag,
                                                                ///< 0 if the tag is not an extension tag
        };

        /** Event: A tag was added or removed */
        valueobject TagEvent extends idl.Event {
            vector<TagChangeInfo> tags;                         ///< Affected tags
            vector<TagInfo> allTags;                            ///< New list of detected tags after change
        };

        /** Event: A tag was added */
        valueobject TagAddedEvent extends TagEvent { };
        /** Event: A tag was removed */
        valueobject TagRemovedEvent extends TagEvent { };

        /** Enumeration: State of firmware update */
        enumeration FirmwareUpdateState {
            UPDATE_STARTED,                                     ///< Update is running
            UPDATE_SUCCESSFUL,                                  ///< Update was completed successfully
            UPDATE_FAILED                                       ///< Update has failed
        };

        /** Event: Firmware update on main strip was started or has finished */
        valueobject FirmwareUpdateStateChangedEvent extends idl.Event {
            FirmwareUpdateState state;                          ///< Update state
        };

        /** Event: Tag overflow */
        valueobject BladeOverflowChangedEvent extends idl.Event {
            boolean overflow;                                   ///< Whether the strip is out of space
                                                                ///< for new blade extension tags
        };

        /** Event: Detected strip orientation has changed */
        valueobject OrientationChangedEvent extends idl.Event {
            AssetStripConfig_1_0_1.Orientation oldOrientation;  ///< Strip orientation before change
            AssetStripConfig_1_0_1.Orientation newOrientation;  ///< Strip orientation after change
        };

        /** Event: Strip composition has changed */
        valueobject CompositionChangedEvent extends idl.Event {
            int oldComponentCount;                              ///< Component count before change
            int newComponentCount;                              ///< Component count after change
        };

        /**
         * Get the current state of the %AssetStrip
         *
         * @return State of the Asset Strip
         */
        State getState();

        /**
         * Get static (hardware and firmware) information
         *
         * @return                      Result: hardware and firmware information
         */
        DeviceInfo getDeviceInfo();

        /**
         * Get dynamic (number of tags) information
         *
         * @return                      Result: tag related information
         */
        StripInfo getStripInfo();

        /**
         * Get info with all settings of a rack unit at once
         *
         * @param  rackUnitNumber       rack unit index to get the info for, range 0..rackUnitCount-1
         * @param  info                 Result: info for this rack unit
         * @return NO_ERROR             on success
         * @return ERR_INVALID_PARAM    rack unit count exceeded
         */
        int getRackUnitInfo(in int rackUnitNumber, out RackUnitInfo info);

        /**
         * Get infos with settings for all rack units
         *
         * @return                      Result: the rack unit infos with settings
         */
        vector<RackUnitInfo> getAllRackUnitInfos();

        /**
         * Get the asset tag for a rack unit
         *
         * @param  rackUnitNumber       rack unit index to read the asset tag for, range 0..rackUnitCount-1
         * @param  slotNumber           slot to read the asset tag for, 0 for the main strip, >0 for blades
         * @param  tagInfo              Result: asset tag information
         * @return NO_ERROR             on success
         * @return ERR_INVALID_PARAM    rack unit count exceeded or colum not existing
         * @return ERR_NO_SUCH_OBJECT   no tag connected to this rack unit
         */
        int getTag(in int rackUnitNumber, in int slotNumber, out TagInfo tagInfo);

        /**
         * Get all asset tags of the strip
         *
         * Please note that in case there is not a single tag connected to the
         * strip the resulting list will be empty, only connected tag info
         * structures are returned
         * It is guaranteed that extensions on the main strip are returned
         * before any tag on an extension itself.
         *
         * @return                      Result: list asset tag infos
         */
        vector<TagInfo> getAllTags();

        /**
         * Get all asset tags on the main strip
         *
         * Same as getAllTags, but only consider tags connected to the main
         * asset strip and not on any connected extension.
         * Extensions on the main strip themselves are returned.
         *
         * @return                      Result: list asset tag infos
         */
        vector<TagInfo> getMainTags();

        /**
         * Get all asset tags on an extension
         *
         * Gets all tags on a single extension for a certain rack unit.
         * List will be empty if there are no tags connected
         *
         * @param  rackUnitNumber       rack unit index to get the extension tags for, range 0..rackUnitCount-1
         * @param  tags                 Result: list asset tag infos
         * @return NO_ERROR             on success
         * @return ERR_INVALID_PARAM    rack unit count exceeded or rack unit
         *                              does not contain an extension
         */
        int getExtensionTags(in int rackUnitNumber, out vector<TagInfo> tags);

        /**
         * Trigger a powercycle of either the whole asset strip port or the
         * LED part power supply on the asset strip
         *
         * @param  hard                 true=whole port, false=LEDs only
         */
        void triggerPowercycle(in boolean hard);

        /**
         * Program custom tag IDs
         *
         * Asset tags of type AMT-P may be programmed by user (custom ID). This method
         * takes a list of (rack unit index, slot number, id) tuples that determine
         * which connected tag should be programmed with which ID.
         * TagInfo::rawId specifies the ID. An empty string erases the current
         * custom ID which brings back the original 1-wire ID.
         * Set TagInfo::slotNumber to 0 for tags on main strip and > 0 for blades.
         * TagInfo::familyDesc and TagInfo::programmable are ignored.
         *
         * @param tagInfos               vector of tag information that will be programmed
         * @return NO_ERROR              on success
         * @return ERR_INVALID_PARAM     rack unit out of bounds or custom ID too long
         * @return ERR_NO_SUCH_OBJECT    rack unit does not exist or has no tag
         * @return ERR_NOT_SUPPORTED     tag is not programmable
         * @return ERR_OPERATION_FAILED  programming failed
         */
        int programTagIDs(in vector<TagInfo> tagInfos);

        /**
         * Retrieve state of firmware update on main strip
         *
         * @return asset strip firmware update state
         */
        FirmwareUpdateState getFirmwareUpdateState();
    };
}

#endif /* __ASSETMGRMODEL_ASSETSTRIP_IDL__ */
