/**

@page subscribtions Subscriptions

Sysrepo allows managed applications / plugins to subscribe for two types of asynchronous events:

- change in the running datastore (@ref rds_subscriptions),
- request for state data (@ref data_providers).

Both types of subscriptions are explained below in more detail. 

@section callbacks Callbacks and threading model
Each of the subscriptions works on the base of asynchronous callbacks - pointers to functions that
will be called upon desired event. For asynchornous event delivery, Sysrepo automatically 
creates a new thread in the managed application (or in plugin daemon in case of a Sysrepo plugins)
behind the scenes. It is always one thread, no matter how many subscriptions you have. This has
the following implications:

- All events will be delivered to a different thread than your application uses for its usual job. If
your callbacks are manipulating any data structures used also in the main/other threads, you will 
need to use some locking mechanism.
- All events will be delivered synchronously into your application: a callback won't be executed
until the previous callback have returned.

@note Pay special attention by executing sysrepo API calls from callbacks. Sysrepo API calls are blocking.
If the API call (e.g. ::sr_commit) results into a different callback to be called in the same application,
the second one cannot be executed until the first one returns (in case of ::sr_commit, you will most
likely get a commit timeout error). If you need this behavior, start a new thread to execute the
API call and return from the callback immediately.

@note The same threading model applies also to @ref plugins, but with one important note - all plugins share the
same thread for the event delivery.

In case that the application needs (or wants) to have callbacks called in its main thread, it can use
the application-local file descriptor watcher API: ::sr_fd_watcher_init. In this case,
the application will be responsible for monitoring events on a set of file descriptors used by Sysrepo
and calling ::sr_fd_event_process whenever any event comes (can be combined with POSIX asynchronous I/O mechanisms
like `select` or `poll`, or with some of the modern event loop libraries like `libevent`, `libev`, `libuv`, etc.).

@section rds_subscriptions Running datastore subscriptions

These subscriptions can be used to notify managed applications / plugins about changes
made in the running datastore. As explained in @ref rds section, by default the
configuration of a model in the running datastore is not accessible. Subscribing
for changes in the runnig datastore also enables the configuration in the
running datastore for relevant data subtrees.

There are two API calls that can be used to subscribe for changes in the running datastore and 
to enable the configuration in the running datastore at the same time:

- ::sr_module_change_subscribe - this API call enables the whole configuration described by a module.
Internally the startup configuration of the module is copied to running datastore.
All nodes of the module is marked as enabled thus the get & edit-like operations can
be issued to the content of the module. Since the configuration nodes defined by augments
and submodules are by design stored in the datafile of the module the belongs to, they are enabled & copied
together with the main module. (e.g.: If you have installed `ietf-interfaces` and `ietf-ip` yang models
on your system. Calling sr_module_change_subscribe for `ietf-interfaces` enables also the configuration
defined by `ietf-ip` module.)

- ::sr_subtree_change_subscribe  - the selected subtree of the configuration can be enabled by this API. For xpath argument of this API call
use xpath expression without predicates. Despite the module-level subscription covers many use-case. There are situations when user wants to be
subscribed only for a subtree. In some cases only a part of the configuration defined by a model
is covered by the application and the other part might be covered by another application. Splitting the logic
of applying the changes might by another reason for using the call. As the name suggests, only a part of the configuration is enabled & copied.
The subsequent table explains what nodes are enabled.

i.e: Subscription for subtree defined by xpath `/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address`
# | Enabled nodes  | Enabled nodes in the example
--|------------- | -------------
1.|the nodes mentioned in the xpath | `/ietf:interfaces`, `/ietf:interfaces/interface`, `/ietf:interfaces/interface/ietf-ip:ipv4`, `/ietf:interfaces/interface/ietf-ip:ipv4/address`
2.|the keys of the lists in the path | `/ietf:interfaces/interface/name`
3.|mandatory nodes that are direct children of a node in the path | `/ietf:interfaces/interface/type`
4.|whole content of a container or a list, if it is the last node the in the path| `/ietf:interfaces/interface/ietf-ip:ipv4/address/ip`, `/ietf:interfaces/interface/ietf-ip:ipv4/address/subnet`

@note Beware when using ::sr_subtree_change_subscribe nodes that are needed to evaluate `when` or `must` statements
might not be enabled if they don't match the list of enabled nodes above, which may lead to validation errors.

@section data_providers Data provider subscriptions
Another type of subscription used with regards to running datastore is the one for providing state data: ::sr_dp_get_items_subscribe.
This call allows the managed application to provide current state data (`config false` in YANG model)
in case that someone have asked for them.

The xpath used is in this API mustn't contains any predicate, it should identify the subtree that subscriber is
providing state data for. Subsequently, when the sysrepo is asked for the state data it calls the callback that is supposed
to return expected state data. The callback is given an xpath that identifies the data that sysrepo expects. In general
callback might be called multiple times with different xpath to handle one user request. The aim of this paragraph is to explain what xpath
the application will be asked by sysrepo for the particular subscription and model.

@subsection stateDataLeaf Top-level leaf/leaf-list

~~~~~~~~~~~~~~~{.c}
module demo {
   /*..*/
   leaf state_data {
      type string;
      config false;
   }
   leaf-list values {
      type uint32;
      config false;
   }
   /* config data */
}
~~~~~~~~~~~~~~~
To provide leaf or leaf-list at top level you have to specify their xpath in subscription call.
~~~~~~~~~~~~~~~{.c}
rc = sr_dp_get_items_subscribe(session, "/demo:state_data", dp_state_data, private_ctx, SR_SUBSCR_DEFAULT, &subscription);

rc = sr_dp_get_items_subscribe(session, "/demo:values", dp_values, private_ctx, SR_SUBSCR_CTX_REUSE, &subscription);
~~~~~~~~~~~~~~~
Each callback will be called once with the xpath that was used in subscribe call. Callback will be called if the user
request particular node.

# | Xpath requested by sysrepo  | Example of xpath returned by data provider
--|------------- | -------------
.|`/demo:state_data`| `/demo:sensors/temperature`, `/demo:sensors/humidity`
.|`/demo:values`| ```/demo:values[.='0']```,```/demo:values[.='1']```, ...

@note Alternatively leaf-list value can be omitted from xpath `/demo:values` works as well.

@subsection stateDataStructure State data structure container/list

~~~~~~~~~~~~~~~{.c}
module demo {
   /*..*/
   container sensors {
      config false;
      leaf temperature {
         type uint16;
      }
      leaf humidity {
         type decimal64 {
            fraction-digits 2;
         }
      }
   }

   list seats {
      config false;
      key number;
      leaf number {
         type uint32;
      }
      leaf name {
         type string;
      }
   }
   /* config data */
}
~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~{.c}
rc = sr_dp_get_items_subscribe(session, "/demo:sensors", dp_sensors, private_ctx, SR_SUBSCR_DEFAULT, &subscription);

rc = sr_dp_get_items_subscribe(session, "/demo:seats", dp_seats, private_ctx, SR_SUBSCR_CTX_REUSE, &subscription);
~~~~~~~~~~~~~~~

If a user requests a node from the container or the list, sysrepo will ask for `/demo:sensors` or `/demo:seats`. (In the current
implementation the sysrepo does not ask for particular node such as `/demo:sensors/temperature`)

# | Xpath requested by sysrepo  | Example of xpath returned by data provider
--|------------- | -------------
1.|`/demo:sensors`| `/demo:sensors/temperature` and `/demo:sensors/humidity`
2.|`/demo:seats`| ```/demo:seats[number='0']```, ```/demo:seats[number='0']/name```, ```/demo:seats[number='1']```, ```/demo:seats[number='1']/name```, ...

@note List doesn't have to be created explicitely: ```/demo:seats[number='0']``` can be omitted. ```/demo:seats[number='0']/name``` will create list instance with key `name` equal to `0` if it does not exist.


@subsection stateDataNested State data container/list with nested structure
~~~~~~~~~~~~~~~{.c}
module demo {
   /*..*/
   container traffic_stats {
     config false;

     leaf number_of_accidents {
        type uint8;
     }

     list cross_road {

       key id;
       leaf id {
          type uint32;
       }


       leaf average_wait_time {
          type uint32;
       }

       list traffic_light {
          key name;
          leaf name {
             type string;
          }
          leaf color {
             type enumeration {
                enum "red" {
                   value 0;
                }

                enum "orange" {
                   value 1;
                }

                enum "green" {
                   value 2;
                }

             }
          }
       }
       container advanced_info {
          leaf longitude {
             type string;
          }

          leaf latitude {
             type string;
          }
       }

     }
}
   /* config data */
}
~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~{.c}
rc = sr_dp_get_items_subscribe(session, "/demo:traffic_stats", dp_traffic_stats, private_ctx, SR_SUBSCR_DEFAULT, &subscription);
~~~~~~~~~~~~~~~
If a user requests data from `traffic_stats` container provider's callback will be called multiple times with different xpath.
Following table summarize the sequence of the requests from sysrepo and expected values from data provider.

# | Xpath requested by sysrepo  | Example of xpath returned by data provider
--|------------- | -------------
1.|`/demo:traffic_stats` provider is supposed to return all leaves and leaf-lists values within it  | `/demo:traffic_stats/number_of_accidents`
2.|`/demo:traffic_stats/cross_road` provider is supposed to return all leaves and leaf-lists values within all instances of the list | ```/demo:traffic_stats/cross_road[id='0']```, ```/demo:traffic_stats/cross_road[id='0']/average_wait_time```, ```/demo:traffic_stats/cross_road[id='1']```, ```/demo:traffic_stats/cross_road[id='1']/average_wait_time```, ...
3.|```/demo:traffic_stats/cross_road[id='X']/traffic_light``` callback will be called for each list instance returned from previous call with list keys properly filled in xpath (X will be replaced by the actual value of the key). Data provider is supposed to return all list instances. | For the xpath ```/demo:traffic_stats/cross_road[id='0']/traffic_light``` provider is supposed to return ```/demo:traffic_stats/cross_road[id='0']/traffic_light[name='A']/color```, ```/demo:traffic_stats/cross_road[id='0']/traffic_light[name='B']/color```, ...
4.|```/demo:traffic_stats/cross_road[id='X']/advanced_info``` callback will be called for each list instance returned from previous call with list keys properly filled in xpath.(X will be replaced by the actual value of the key). User is supposed to return the content of the container. | For the xpath ```/demo:traffic_stats/cross_road[id='0']/advanced_info``` provider is supposed to return values with xpath ```/demo:traffic_stats/cross_road[id='0']/advanced_info/longitude```, ```/demo:traffic_stats/cross_road[id='0']/advanced_info/latitude```


@subsection stateDataInConfig State data nodes in configuration container/list
~~~~~~~~~~~~~~~{.c}
module demo {
   /*..*/

   list abc {
      key cfg;
      leaf cfg {
         type string;
      }

      leaf name {
         type string;
      }

      leaf value {
         type string;
         config false;
      }

   }
   /* config data */

}
~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~{.c}

rc = sr_dp_get_items_subscribe(session, "/demo:abc/value", dp_value, private_ctx, SR_SUBSCR_DEFAULT, &subscription);
~~~~~~~~~~~~~~~

Data provider will be asked for xpaths with keys filled (corresponding to currently configured lists `/demo:abc`) he is supposed to return leaf for the particular instance.
# | Xpath requested by sysrepo  | Example of xpath returned by data provider
--|------------- | -------------
1.|```/demo:abc[cfg='X']/value``` callback will be called for each configured list instance. (X will be replaced by the actual value of the key). User is supposed to return value of the leaf. |  For the xpath ```/demo:abc[cfg='0']/value``` provider is supposed to return value of the leaf.

*/
