/**
 * This module is taken from the standard CORBA Notification Service
 * 1.1, as described in:
 *
 * https://www.omg.org/spec/NOT/1.1/
 *
 * The idl was extracted from the following PDF:
 * formal/04-10-13
 */

#ifndef _COS_NOTIFY_CHANNEL_ADMIN_IDL_
#define _COS_NOTIFY_CHANNEL_ADMIN_IDL_

#include "CosNotification.idl"
#include "CosNotifyFilter.idl"
#include "CosNotifyComm.idl"
#include "CosEventChannelAdmin.idl"

#pragma prefix "omg.org"

module CosNotifyChannelAdmin {

   exception ConnectionAlreadyActive {};
   exception ConnectionAlreadyInactive {};
   exception NotConnected {};

   // Forward declarations
   interface ConsumerAdmin;
   interface SupplierAdmin;
   interface EventChannel;
   interface EventChannelFactory;

   enum ProxyType {
      PUSH_ANY,
      PULL_ANY,
      PUSH_STRUCTURED,
      PULL_STRUCTURED,
      PUSH_SEQUENCE,
      PULL_SEQUENCE,
      PUSH_TYPED,
      PULL_TYPED
   };

   enum ObtainInfoMode {
      ALL_NOW_UPDATES_OFF,
      ALL_NOW_UPDATES_ON,
      NONE_NOW_UPDATES_OFF,
      NONE_NOW_UPDATES_ON
   };

   interface ProxyConsumer :
         CosNotification::QoSAdmin,
         CosNotifyFilter::FilterAdmin {

      readonly attribute ProxyType MyType;
      readonly attribute SupplierAdmin MyAdmin;

      CosNotification::EventTypeSeq obtain_subscription_types(
            in ObtainInfoMode mode );

      void validate_event_qos (
            in CosNotification::QoSProperties required_qos,
            out CosNotification::NamedPropertyRangeSeq available_qos)
         raises (CosNotification::UnsupportedQoS);

   }; // ProxyConsumer

   interface ProxySupplier :
         CosNotification::QoSAdmin,
         CosNotifyFilter::FilterAdmin {

      readonly attribute ProxyType MyType;
      readonly attribute ConsumerAdmin MyAdmin;

      attribute CosNotifyFilter::MappingFilter priority_filter;
      attribute CosNotifyFilter::MappingFilter lifetime_filter;

      CosNotification::EventTypeSeq obtain_offered_types(
            in ObtainInfoMode mode );

      void validate_event_qos (
            in CosNotification::QoSProperties required_qos,
            out CosNotification::NamedPropertyRangeSeq available_qos)
         raises (CosNotification::UnsupportedQoS);

   }; // ProxySupplier

   interface ProxyPushConsumer :
         ProxyConsumer,
         CosNotifyComm::PushConsumer {

      void connect_any_push_supplier (
            in CosEventComm::PushSupplier push_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // ProxyPushConsumer

   interface StructuredProxyPushConsumer :
         ProxyConsumer,
         CosNotifyComm::StructuredPushConsumer {

      void connect_structured_push_supplier (
            in CosNotifyComm::StructuredPushSupplier push_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // StructuredProxyPushConsumer

   interface SequenceProxyPushConsumer :
         ProxyConsumer,
         CosNotifyComm::SequencePushConsumer {

      void connect_sequence_push_supplier (
            in CosNotifyComm::SequencePushSupplier push_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // SequenceProxyPushConsumer

   interface ProxyPullSupplier :
         ProxySupplier,
         CosNotifyComm::PullSupplier {

      void connect_any_pull_consumer (
            in CosEventComm::PullConsumer pull_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // ProxyPullSupplier

   interface StructuredProxyPullSupplier :
         ProxySupplier,
         CosNotifyComm::StructuredPullSupplier {

      void connect_structured_pull_consumer (
            in CosNotifyComm::StructuredPullConsumer pull_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // StructuredProxyPullSupplier

   interface SequenceProxyPullSupplier :
         ProxySupplier,
         CosNotifyComm::SequencePullSupplier {

      void connect_sequence_pull_consumer (
            in CosNotifyComm::SequencePullConsumer pull_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected);

   }; // SequenceProxyPullSupplier

   interface ProxyPullConsumer :
         ProxyConsumer,
         CosNotifyComm::PullConsumer {

      void connect_any_pull_supplier (
            in CosEventComm::PullSupplier pull_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // ProxyPullConsumer

   interface StructuredProxyPullConsumer :
         ProxyConsumer,
         CosNotifyComm::StructuredPullConsumer {

      void connect_structured_pull_supplier (
            in CosNotifyComm::StructuredPullSupplier pull_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // StructuredProxyPullConsumer

   interface SequenceProxyPullConsumer :
         ProxyConsumer,
         CosNotifyComm::SequencePullConsumer {

      void connect_sequence_pull_supplier (
            in CosNotifyComm::SequencePullSupplier pull_supplier)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // SequenceProxyPullConsumer

   interface ProxyPushSupplier :
         ProxySupplier,
         CosNotifyComm::PushSupplier {

      void connect_any_push_consumer (
            in CosEventComm::PushConsumer push_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // ProxyPushSupplier

   interface StructuredProxyPushSupplier :
         ProxySupplier,
         CosNotifyComm::StructuredPushSupplier {

      void connect_structured_push_consumer (
            in CosNotifyComm::StructuredPushConsumer push_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // StructuredProxyPushSupplier

   interface SequenceProxyPushSupplier :
         ProxySupplier,
         CosNotifyComm::SequencePushSupplier {

      void connect_sequence_push_consumer (
            in CosNotifyComm::SequencePushConsumer push_consumer)
         raises(CosEventChannelAdmin::AlreadyConnected,
                CosEventChannelAdmin::TypeError );

      void suspend_connection()
         raises(ConnectionAlreadyInactive, NotConnected);

      void resume_connection()
         raises(ConnectionAlreadyActive, NotConnected);

   }; // SequenceProxyPushSupplier

   typedef long ProxyID;
   typedef sequence <ProxyID> ProxyIDSeq;

   enum ClientType {
      ANY_EVENT,
      STRUCTURED_EVENT,
      SEQUENCE_EVENT
   };

   enum InterFilterGroupOperator { AND_OP, OR_OP };

   typedef long AdminID;
   typedef sequence<AdminID> AdminIDSeq;

   exception AdminNotFound {};
   exception ProxyNotFound {};

   struct AdminLimit {
      CosNotification::PropertyName name;
      CosNotification::PropertyValue value;
   };

   exception AdminLimitExceeded { AdminLimit admin_property_err; };

   interface ConsumerAdmin :
         CosNotification::QoSAdmin,
         CosNotifyComm::NotifySubscribe,
         CosNotifyFilter::FilterAdmin,
         CosEventChannelAdmin::ConsumerAdmin {

      readonly attribute AdminID MyID;
      readonly attribute EventChannel MyChannel;

      readonly attribute InterFilterGroupOperator MyOperator;

      attribute CosNotifyFilter::MappingFilter priority_filter;
      attribute CosNotifyFilter::MappingFilter lifetime_filter;

      readonly attribute ProxyIDSeq pull_suppliers;
      readonly attribute ProxyIDSeq push_suppliers;

      ProxySupplier get_proxy_supplier ( in ProxyID proxy_id )
         raises ( ProxyNotFound );

      ProxySupplier obtain_notification_pull_supplier (
            in ClientType ctype,
            out ProxyID proxy_id)
         raises ( AdminLimitExceeded );

      ProxySupplier obtain_notification_push_supplier (
            in ClientType ctype,
            out ProxyID proxy_id)
         raises ( AdminLimitExceeded );

      void destroy();

   }; // ConsumerAdmin

   interface SupplierAdmin :
         CosNotification::QoSAdmin,
         CosNotifyComm::NotifyPublish,
         CosNotifyFilter::FilterAdmin,
         CosEventChannelAdmin::SupplierAdmin {

      readonly attribute AdminID MyID;
      readonly attribute EventChannel MyChannel;

      readonly attribute InterFilterGroupOperator MyOperator;

      readonly attribute ProxyIDSeq pull_consumers;
      readonly attribute ProxyIDSeq push_consumers;

      ProxyConsumer get_proxy_consumer ( in ProxyID proxy_id )
         raises ( ProxyNotFound );

      ProxyConsumer obtain_notification_pull_consumer (
            in ClientType ctype,
            out ProxyID proxy_id)
         raises ( AdminLimitExceeded );

      ProxyConsumer obtain_notification_push_consumer (
            in ClientType ctype,
            out ProxyID proxy_id)
         raises ( AdminLimitExceeded );

      void destroy();

   }; // SupplierAdmin

   interface EventChannel :
      CosNotification::QoSAdmin,
      CosNotification::AdminPropertiesAdmin,
      CosEventChannelAdmin::EventChannel {

      readonly attribute EventChannelFactory MyFactory;

      readonly attribute ConsumerAdmin default_consumer_admin;
      readonly attribute SupplierAdmin default_supplier_admin;

      readonly attribute CosNotifyFilter::FilterFactory
                  default_filter_factory;

      ConsumerAdmin new_for_consumers(
            in InterFilterGroupOperator op,
            out AdminID id );

      SupplierAdmin new_for_suppliers(
            in InterFilterGroupOperator op,
            out AdminID id );

      ConsumerAdmin get_consumeradmin ( in AdminID id )
         raises (AdminNotFound);

      SupplierAdmin get_supplieradmin ( in AdminID id )
         raises (AdminNotFound);

      AdminIDSeq get_all_consumeradmins();
      AdminIDSeq get_all_supplieradmins();

   }; // EventChannel

   typedef long ChannelID;
   typedef sequence<ChannelID> ChannelIDSeq;

   exception ChannelNotFound {};

   interface EventChannelFactory {

      EventChannel create_channel (
            in CosNotification::QoSProperties initial_qos,
            in CosNotification::AdminProperties initial_admin,
            out ChannelID id)
         raises(CosNotification::UnsupportedQoS,
                CosNotification::UnsupportedAdmin );

      ChannelIDSeq get_all_channels();

      EventChannel get_event_channel ( in ChannelID id )
         raises (ChannelNotFound);

   }; // EventChannelFactory
   
}; // CosNotifyChannelAdmin

#endif /* _COS_NOTIFY_CHANNEL_ADMIN_IDL_ */
