aboutsummaryrefslogtreecommitdiffstats
path: root/test/mocks/pnfsimulator/netconfsimulator/netopeer-change-saver-native/sysrepo.h
blob: 9d541d1c09bf0bebfabb5351f1ca954074a81c4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
/**
 * @file sysrepo.h
 * @author Rastislav Szabo <raszabo@cisco.com>, Lukas Macko <lmacko@cisco.com>
 * @brief Sysrepo Client Library public API.
 *
 * @copyright
 * Copyright 2015 Cisco Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SYSREPO_H_
#define SYSREPO_H_

/**
 * @defgroup cl Client Library
 * @{
 *
 * @brief Provides the public API towards applications using sysrepo to store
 * their configuration data, or towards management agents.
 *
 * Communicates with Sysrepo Engine (@ref cm), which is running either inside
 * of dedicated sysrepo daemon, or within this library if daemon is not alive.
 *
 * Access to the sysrepo datastore is connection- and session- oriented. Before
 * calling any data access/manipulation API, one needs to connect to the datastore
 * via ::sr_connect and open a session via ::sr_session_start. One connection
 * can serve multiple sessions.
 *
 * Each data access/manipulation request call is blocking - blocks the connection
 * until the response from Sysrepo Engine comes, or until an error occurs. It is
 * safe to call multiple requests on the same session (or different session that
 * belongs to the same connection) from multiple threads at the same time,
 * however it is not effective, since each call is blocked until previous one
 * finishes. If you need fast multi-threaded access to sysrepo, use a dedicated
 * connection for each thread.
 *
 * @see
 * See @ref main_page "Sysrepo Introduction" for details about sysrepo architecture.
 * @see
 * @ref xp_page "XPath Addressing" is used for node identification in data-related calls.
 */

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#ifdef __APPLE__
    #include <sys/types.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

////////////////////////////////////////////////////////////////////////////////
// Common typedefs and API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Sysrepo connection context used to identify a connection to sysrepo datastore.
 */
typedef struct sr_conn_ctx_s sr_conn_ctx_t;

/**
 * @brief Sysrepo session context used to identify a configuration session.
 */
typedef struct sr_session_ctx_s sr_session_ctx_t;

/**
 * @brief Memory context used for efficient memory management for values, trees and GPB messages.
 */
typedef struct sr_mem_ctx_s sr_mem_ctx_t;

/**
 * @brief Possible types of an data element stored in the sysrepo datastore.
 */
typedef enum sr_type_e {
    /* special types that does not contain any data */
    SR_UNKNOWN_T,              /**< Element unknown to sysrepo (unsupported element). */
    SR_TREE_ITERATOR_T,        /**< Special type of tree node used to store all data needed for iterative tree loading. */

    SR_LIST_T,                 /**< List instance. ([RFC 6020 sec 7.8](http://tools.ietf.org/html/rfc6020#section-7.8)) */
    SR_CONTAINER_T,            /**< Non-presence container. ([RFC 6020 sec 7.5](http://tools.ietf.org/html/rfc6020#section-7.5)) */
    SR_CONTAINER_PRESENCE_T,   /**< Presence container. ([RFC 6020 sec 7.5.1](http://tools.ietf.org/html/rfc6020#section-7.5.1)) */
    SR_LEAF_EMPTY_T,           /**< A leaf that does not hold any value ([RFC 6020 sec 9.11](http://tools.ietf.org/html/rfc6020#section-9.11)) */
    SR_NOTIFICATION_T,         /**< Notification instance ([RFC 7095 sec 7.16](https://tools.ietf.org/html/rfc7950#section-7.16)) */

    /* types containing some data */
    SR_BINARY_T,       /**< Base64-encoded binary data ([RFC 6020 sec 9.8](http://tools.ietf.org/html/rfc6020#section-9.8)) */
    SR_BITS_T,         /**< A set of bits or flags ([RFC 6020 sec 9.7](http://tools.ietf.org/html/rfc6020#section-9.7)) */
    SR_BOOL_T,         /**< A boolean value ([RFC 6020 sec 9.5](http://tools.ietf.org/html/rfc6020#section-9.5)) */
    SR_DECIMAL64_T,    /**< 64-bit signed decimal number ([RFC 6020 sec 9.3](http://tools.ietf.org/html/rfc6020#section-9.3)) */
    SR_ENUM_T,         /**< A string from enumerated strings list ([RFC 6020 sec 9.6](http://tools.ietf.org/html/rfc6020#section-9.6)) */
    SR_IDENTITYREF_T,  /**< A reference to an abstract identity ([RFC 6020 sec 9.10](http://tools.ietf.org/html/rfc6020#section-9.10)) */
    SR_INSTANCEID_T,   /**< References a data tree node ([RFC 6020 sec 9.13](http://tools.ietf.org/html/rfc6020#section-9.13)) */
    SR_INT8_T,         /**< 8-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_INT16_T,        /**< 16-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_INT32_T,        /**< 32-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_INT64_T,        /**< 64-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_STRING_T,       /**< Human-readable string ([RFC 6020 sec 9.4](http://tools.ietf.org/html/rfc6020#section-9.4)) */
    SR_UINT8_T,        /**< 8-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_UINT16_T,       /**< 16-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_UINT32_T,       /**< 32-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_UINT64_T,       /**< 64-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    SR_ANYXML_T,       /**< Unknown chunk of XML ([RFC 6020 sec 7.10](https://tools.ietf.org/html/rfc6020#section-7.10)) */
    SR_ANYDATA_T,      /**< Unknown set of nodes, encoded in XML ([RFC 7950 sec 7.10](https://tools.ietf.org/html/rfc7950#section-7.10)) */
} sr_type_t;

/**
 * @brief Data of an element (if applicable), properly set according to the type.
 */
typedef union sr_data_u {
    char *binary_val;       /**< Base64-encoded binary data ([RFC 6020 sec 9.8](http://tools.ietf.org/html/rfc6020#section-9.8)) */
    char *bits_val;         /**< A set of bits or flags ([RFC 6020 sec 9.7](http://tools.ietf.org/html/rfc6020#section-9.7)) */
    bool bool_val;          /**< A boolean value ([RFC 6020 sec 9.5](http://tools.ietf.org/html/rfc6020#section-9.5)) */
    double decimal64_val;   /**< 64-bit signed decimal number ([RFC 6020 sec 9.3](http://tools.ietf.org/html/rfc6020#section-9.3)) */
    char *enum_val;         /**< A string from enumerated strings list ([RFC 6020 sec 9.6](http://tools.ietf.org/html/rfc6020#section-9.6)) */
    char *identityref_val;  /**< A reference to an abstract identity ([RFC 6020 sec 9.10](http://tools.ietf.org/html/rfc6020#section-9.10)) */
    char *instanceid_val;   /**< References a data tree node ([RFC 6020 sec 9.13](http://tools.ietf.org/html/rfc6020#section-9.13)) */
    int8_t int8_val;        /**< 8-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    int16_t int16_val;      /**< 16-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    int32_t int32_val;      /**< 32-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    int64_t int64_val;      /**< 64-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    char *string_val;       /**< Human-readable string ([RFC 6020 sec 9.4](http://tools.ietf.org/html/rfc6020#section-9.4)) */
    uint8_t uint8_val;      /**< 8-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    uint16_t uint16_val;    /**< 16-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    uint32_t uint32_val;    /**< 32-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    uint64_t uint64_val;    /**< 64-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
    char *anyxml_val;       /**< Unknown chunk of XML ([RFC 6020 sec 7.10](https://tools.ietf.org/html/rfc6020#section-7.10)) */
    char *anydata_val;      /**< Unknown set of nodes, encoded in XML ([RFC 7950 sec 7.10](https://tools.ietf.org/html/rfc7950#section-7.10)) */
} sr_data_t;

/**
 * @brief Structure that contains value of an data element stored in the sysrepo datastore.
 */
typedef struct sr_val_s {
    /**
     * Memory context used internally by Sysrepo for efficient storage
     * and conversion of this structure.
     */
    sr_mem_ctx_t *_sr_mem;

    /**
     * XPath identifier of the data element, as defined in
     * @ref xp_page "Path Addressing" documentation
     */
    char *xpath;

    /** Type of an element. */
    sr_type_t type;

    /**
     * Flag for node with default value (applicable only for leaves).
     * It is set to TRUE only if the value was *implicitly* set by the datastore as per
     * module schema. Explicitly set/modified data element (through the sysrepo API) always
     * has this flag unset regardless of the entered value.
     */
    bool dflt;

    /** Data of an element (if applicable), properly set according to the type. */
    sr_data_t data;

} sr_val_t;

/**
 * @brief A data element stored in the sysrepo datastore represented as a tree node.
 *
 * @note Can be safely casted to ::sr_val_t, only *xpath* member will point to node name rather
 * than to an actual xpath.
 */
typedef struct sr_node_s {
    /**
     * Memory context used internally by Sysrepo for efficient storage
     * and conversion of this structure.
     */
    sr_mem_ctx_t *_sr_mem;

    /** Name of the node. */
    char *name;

    /** Type of an element. */
    sr_type_t type;

    /** Flag for default node (applicable only for leaves). */
    bool dflt;

    /** Data of an element (if applicable), properly set according to the type. */
    sr_data_t data;

    /**
     * Name of the module that defines scheme of this node.
     * NULL if it is the same as that of the predecessor.
     */
    char *module_name;

    /** Pointer to the parent node (NULL in case of root node). */
    struct sr_node_s *parent;

    /** Pointer to the next sibling node (NULL if there is no one). */
    struct sr_node_s *next;

    /** Pointer to the previous sibling node (NULL if there is no one). */
    struct sr_node_s *prev;

    /** Pointer to the first child node (NULL if this is a leaf). */
    struct sr_node_s *first_child;

    /** Pointer to the last child node (NULL if this is a leaf). */
    struct sr_node_s *last_child;
} sr_node_t;

/**
 * @brief Sysrepo error codes.
 */
typedef enum sr_error_e {
    SR_ERR_OK = 0,             /**< No error. */
    SR_ERR_INVAL_ARG,          /**< Invalid argument. */
    SR_ERR_NOMEM,              /**< Not enough memory. */
    SR_ERR_NOT_FOUND,          /**< Item not found. */
    SR_ERR_INTERNAL,           /**< Other internal error. */
    SR_ERR_INIT_FAILED,        /**< Sysrepo infra initialization failed. */
    SR_ERR_IO,                 /**< Input/Output error. */
    SR_ERR_DISCONNECT,         /**< The peer disconnected. */
    SR_ERR_MALFORMED_MSG,      /**< Malformed message. */
    SR_ERR_UNSUPPORTED,        /**< Unsupported operation requested. */
    SR_ERR_UNKNOWN_MODEL,      /**< Request includes unknown schema */
    SR_ERR_BAD_ELEMENT,        /**< Unknown element in existing schema */
    SR_ERR_VALIDATION_FAILED,  /**< Validation of the changes failed. */
    SR_ERR_OPERATION_FAILED,   /**< An operation failed. */
    SR_ERR_DATA_EXISTS,        /**< Item already exists. */
    SR_ERR_DATA_MISSING,       /**< Item does not exists. */
    SR_ERR_UNAUTHORIZED,       /**< Operation not authorized. */
    SR_ERR_INVAL_USER,         /**< Invalid username. */
    SR_ERR_LOCKED,             /**< Requested resource is already locked. */
    SR_ERR_TIME_OUT,           /**< Time out has expired. */
    SR_ERR_RESTART_NEEDED,     /**< Sysrepo Engine restart is needed. */
    SR_ERR_VERSION_MISMATCH,   /**< Incompatible client library used to communicate with sysrepo. */
} sr_error_t;

/**
 * @brief Detailed sysrepo error information.
 */
typedef struct sr_error_info_s {
    const char *message;  /**< Error message. */
    const char *xpath;    /**< XPath to the node where the error has been discovered. */
} sr_error_info_t;

/**
 * @brief Returns the error message corresponding to the error code.
 *
 * @param[in] err_code Error code.
 *
 * @return Error message (statically allocated, do not free).
 */
const char *sr_strerror(int err_code);

/**
 * @brief Log levels used to determine if message of certain severity should be printed.
 */
typedef enum {
    SR_LL_NONE,  /**< Do not print any messages. */
    SR_LL_ERR,   /**< Print only error messages. */
    SR_LL_WRN,   /**< Print error and warning messages. */
    SR_LL_INF,   /**< Besides errors and warnings, print some other informational messages. */
    SR_LL_DBG,   /**< Print all messages including some development debug messages. */
} sr_log_level_t;

/**
 * @brief Enables / disables / changes log level (verbosity) of logging to
 * standard error output.
 *
 * By default, logging to stderr is disabled. Setting log level to any value
 * other than SR_LL_NONE enables the logging to stderr. Setting log level
 * back to SR_LL_NONE disables the logging to stderr.
 *
 * @param[in] log_level requested log level (verbosity).
 */
void sr_log_stderr(sr_log_level_t log_level);

/**
 * @brief Enables / disables / changes log level (verbosity) of logging to system log.
 *
 * By default, logging into syslog is disabled. Setting log level to any value
 * other than SR_LL_NONE enables the logging into syslog. Setting log level
 * back to SR_LL_NONE disables the logging into syslog.
 *
 * @note Please note that enabling logging into syslog will overwrite your syslog
 * connection settings (calls openlog), if you are connected to syslog already.
 *
 * @param[in] log_level requested log level (verbosity).
 */
void sr_log_syslog(sr_log_level_t log_level);

/**
 * @brief Sets callback that will be called when a log entry would be populated.
 *
 * @param[in] level Verbosity level of the log entry.
 * @param[in] message Message of the log entry.
 */
typedef void (*sr_log_cb)(sr_log_level_t level, const char *message);

/**
 * @brief Sets callback that will be called when a log entry would be populated.
 * Callback will be called for each message with any log level.
 *
 * @param[in] log_callback Callback to be called when a log entry would populated.
 */
void sr_log_set_cb(sr_log_cb log_callback);


////////////////////////////////////////////////////////////////////////////////
// Connection / Session Management
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Flags used to override default connection handling by ::sr_connect call.
 */
typedef enum sr_conn_flag_e {
    SR_CONN_DEFAULT = 0,          /**< Default behavior - instantiate library-local Sysrepo Engine if
                                       the connection to sysrepo daemon is not possible. */
    SR_CONN_DAEMON_REQUIRED = 1,  /**< Require daemon connection - do not instantiate library-local Sysrepo Engine
                                       if the library cannot connect to the sysrepo daemon  (and return an error instead). */
    SR_CONN_DAEMON_START = 2,     /**< If sysrepo daemon is not running, and SR_CONN_DAEMON_REQUIRED was specified,
                                       start it (only if the process calling ::sr_connect is running under root privileges). */
} sr_conn_flag_t;

/**
 * @brief Options overriding default connection handling by ::sr_connect call,
 * it is supposed to be bitwise OR-ed value of any ::sr_conn_flag_t flags.
 */
typedef uint32_t sr_conn_options_t;

/**
 * @brief Flags used to override default session handling (used by ::sr_session_start
 * and ::sr_session_start_user calls).
 */
typedef enum sr_session_flag_e {
    SR_SESS_DEFAULT = 0,       /**< Default (normal) session behavior. */
    SR_SESS_CONFIG_ONLY = 1,   /**< Session will process only configuration data (e.g. sysrepo won't
                                    return any state data by ::sr_get_items / ::sr_get_items_iter calls). */
    SR_SESS_ENABLE_NACM = 2,   /**< Enable NETCONF access control for this session (disabled by default). */

    SR_SESS_MUTABLE_OPTS = 3   /**< Bit-mask of options that can be set by the user
                                    (immutable flags are defined in sysrepo.proto file). */
} sr_session_flag_t;

/**
 * @brief Options overriding default connection session handling,
 * it is supposed to be bitwise OR-ed value of any ::sr_session_flag_t flags.
 */
typedef uint32_t sr_sess_options_t;

/**
 * @brief Data stores that sysrepo supports. Both are editable via implicit candidate.
 * To make changes permanent in edited datastore ::sr_commit must be issued.
 * @see @ref ds_page "Datastores & Sessions" information page.
 */
typedef enum sr_datastore_e {
    SR_DS_STARTUP = 0,    /**< Contains configuration data that should be loaded by the controlled application when it starts. */
    SR_DS_RUNNING = 1,    /**< Contains currently applied configuration and state data of a running application.
                               @note This datastore is supported only by applications that subscribe for notifications
                               about the changes made in the datastore (e.g. ::sr_module_change_subscribe). */
    SR_DS_CANDIDATE = 2,  /**< Contains configuration that can be manipulated without impacting the current configuration.
                               Its content is set to the content of running datastore by default. Changes made within
                               the candidate can be later committed to the running datastore or copied to any datastore.

                               @note The main difference between working with running and candidate datastore is in commit
                               operation - commit of candidate session causes the content of running configuration to be set
                               the value of the candidate configuration (running datastore is overwritten), whereas commit of
                               runnnig session merges the changes made within the session with the actual state of running. */
} sr_datastore_t;

/**
 * @brief Connects to the sysrepo datastore (Sysrepo Engine).
 *
 * @note If the client library loses connection to the Sysrepo Engine during
 * the lifetime of the application, all Sysrepo API calls will start returning
 * ::SR_ERR_DISCONNECT error on active sessions. In this case, the application is supposed to reconnect
 * with another ::sr_connect call and restart all lost sessions.
 *
 * @param[in] app_name Name of the application connecting to the datastore
 * (can be a static string). Used only for accounting purposes.
 * @param[in] opts Options overriding default connection handling by this call.
 * @param[out] conn_ctx Connection context that can be used for subsequent API calls
 * (automatically allocated, it is supposed to be released by the caller using ::sr_disconnect).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_connect(const char *app_name, const sr_conn_options_t opts, sr_conn_ctx_t **conn_ctx);

/**
 * @brief Disconnects from the sysrepo datastore (Sysrepo Engine).
 *
 * Cleans up and frees connection context allocated by ::sr_connect. All sessions
 * started within the connection will be automatically stopped and cleaned up too.
 *
 * @param[in] conn_ctx Connection context acquired with ::sr_connect call.
 */
void sr_disconnect(sr_conn_ctx_t *conn_ctx);

/**
 * @brief Starts a new configuration session.
 *
 * @see @ref ds_page "Datastores & Sessions" for more information about datastores and sessions.
 *
 * @param[in] conn_ctx Connection context acquired with ::sr_connect call.
 * @param[in] datastore Datastore on which all sysrepo functions within this
 * session will operate. Later on, datastore can be later changed using
 * ::sr_session_switch_ds call. Functionality of some sysrepo calls does not depend on
 * datastore. If your session will contain just calls like these, you can pass
 * any valid value (e.g. SR_RUNNING).
 * @param[in] opts Options overriding default session handling.
 * @param[out] session Session context that can be used for subsequent API
 * calls (automatically allocated, can be released by calling ::sr_session_stop).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_session_start(sr_conn_ctx_t *conn_ctx, const sr_datastore_t datastore,
        const sr_sess_options_t opts, sr_session_ctx_t **session);

/**
 * @brief Starts a new configuration session on behalf of a different user.
 *
 * This call is intended for northbound access to sysrepo from management
 * applications, that need sysrepo to authorize the operations not only
 * against the user under which the management application is running, but
 * also against another user (e.g. user that connected to the management application).
 *
 * @note Be aware that authorization of specified user may fail with unexpected
 * errors in case that the client library uses its own Sysrepo Engine at the
 * moment and your process in not running under root privileges. To prevent
 * this situation, consider specifying SR_CONN_DAEMON_REQUIRED flag by
 * ::sr_connect call or using ::sr_session_start instead of this function.
 *
 * @see @ref ds_page "Datastores & Sessions" for more information about datastores and sessions.
 *
 * @param[in] conn_ctx Connection context acquired with ::sr_connect call.
 * @param[in] user_name Effective user name used to authorize the access to
 * datastore (in addition to automatically-detected real user name).
 * @param[in] datastore Datastore on which all sysrepo functions within this
 * session will operate. Functionality of some sysrepo calls does not depend on
 * datastore. If your session will contain just calls like these, you can pass
 * any valid value (e.g. SR_RUNNING).
 * @param[in] opts Options overriding default session handling.
 * @param[out] session Session context that can be used for subsequent API calls
 * (automatically allocated, it is supposed to be released by caller using ::sr_session_stop).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_session_start_user(sr_conn_ctx_t *conn_ctx, const char *user_name, const sr_datastore_t datastore,
        const sr_sess_options_t opts, sr_session_ctx_t **session);

/**
 * @brief Stops current session and releases resources tied to the session.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_session_stop(sr_session_ctx_t *session);

/**
 * @brief Refreshes configuration data cached within the session and starts
 * operating on fresh data loaded from the datastore.
 *
 * Call this function in case that you leave session open for longer time period
 * and you expect that the data in the datastore may have been changed since
 * last data (re)load (which occurs by ::sr_session_start, ::sr_commit and
 * ::sr_discard_changes).
 *
 * @see @ref ds_page "Datastores & Sessions" for information about session data caching.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_session_refresh(sr_session_ctx_t *session);

/**
 * @brief Checks aliveness and validity of the session & connection tied to it.
 *
 * If the connection to the Sysrepo Engine has been lost in the meantime, returns SR_ERR_DICONNECT.
 * In this case, the application is supposed to stop the session (::sr_session_stop), disconnect (::sr_disconnect)
 * and then reconnect (::sr_connect) and start a new session (::sr_session_start).
 *
 * @note If the client library loses connection to the Sysrepo Engine during the lifetime of the application,
 * all Sysrepo API calls will start returning SR_ERR_DISCONNECT error on active sessions. This is the primary
 * mechanism that can be used to detect connection issues, ::sr_session_check is just an addition to it. Since
 * ::sr_session_check sends a message to the Sysrepo Engine and waits for the response, it costs some extra overhead
 * in contrast to catching SR_ERR_DISCONNECT error.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK in case that the session is healthy,
 * SR_ERR_DICONNECT in case that connection to the Sysrepo Engine has been lost).
 */
int sr_session_check(sr_session_ctx_t *session);

/**
 * @brief Changes datastore to which the session is tied to. All subsequent
 * calls will be issued on the chosen datastore.
 *
 * @param [in] session
 * @param [in] ds
 * @return Error code (SR_ERR_OK on success)
 */
int sr_session_switch_ds(sr_session_ctx_t *session, sr_datastore_t ds);

/**
 * @brief Alter the session options. E.g.: set/unset SR_SESS_CONFIG_ONLY flag.
 *
 * @param [in] session
 * @param [in] opts - new value for session options
 * @return Error code (SR_ERR_OK on success)
 */
int sr_session_set_options(sr_session_ctx_t *session, const sr_sess_options_t opts);

/**
 * @brief Retrieves detailed information about the error that has occurred
 * during the last operation executed within provided session.
 *
 * If multiple errors has occurred within the last operation, only the first
 * one is returned. This call is sufficient for all data retrieval and data
 * manipulation functions that operate on single-item basis. For operations
 * such as ::sr_validate or ::sr_commit where multiple errors can occur,
 * use ::sr_get_last_errors instead.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[out] error_info Detailed error information. Be aware that
 * returned pointer may change by the next API call executed within the provided
 * session,  so it's not safe to use this function by concurrent access to the
 * same session within multiple threads. Do not free or modify returned values.
 *
 * @return Error code of the last operation executed within provided session.
 */
int sr_get_last_error(sr_session_ctx_t *session, const sr_error_info_t **error_info);

/**
 * @brief Retrieves detailed information about all errors that have occurred
 * during the last operation executed within provided session.
 *
 * Use this call instead of ::sr_get_last_error by operations where multiple
 * errors can occur, such as ::sr_validate or ::sr_commit.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[out] error_info Array of detailed error information. Be aware that
 * returned pointer may change by the next API call executed within the provided
 * session,  so it's not safe to use this function by concurrent access to the
 * same session within multiple threads. Do not free or modify returned values.
 * @param[out] error_cnt Number of errors returned in the error_info array.
 *
 * @return Error code of the last operation executed within provided session.
 */
int sr_get_last_errors(sr_session_ctx_t *session, const sr_error_info_t **error_info, size_t *error_cnt);

/**
 * @brief Sets detailed error information into provided session. Used to notify
 * the client library about errors that occurred in application code.
 *
 * @note Intended for commit verifiers (notification session) - the call has no
 * impact on any other sessions.
 *
 * @param[in] session Session context passed into notification callback.
 * @param[in] message Human-readable error message.
 * @param[in] xpath XPath to the node where the error has occurred. NULL value
 * is also accepted.
 *
 * @return Error code (SR_ERR_OK on success)
 */
int sr_set_error(sr_session_ctx_t *session, const char *message, const char *xpath);

/**
 * @brief Returns the assigned id of the session. Can be used to pair the session with
 * netconf-config-change notification initiator.
 * @param [in] session
 * @return session id or 0 in case of error
 */
uint32_t sr_session_get_id(sr_session_ctx_t *session);

////////////////////////////////////////////////////////////////////////////////
// Data Retrieval API (get / get-config functionality)
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Structure that contains information about one particular schema file installed in sysrepo.
 */
typedef struct sr_sch_revision_s {
    const char *revision;         /**< Revision of the module/submodule. */
    const char *file_path_yang;   /**< Absolute path to file where the module/submodule is stored (YANG format). */
    const char *file_path_yin;    /**< Absolute path to file where the module/submodule is stored (.yin format). */
} sr_sch_revision_t;

/**
 * @brief Structure that contains information about submodules of a module installed in sysrepo.
 */
typedef struct sr_sch_submodule_s {
    const char *submodule_name;    /**< Submodule name. */
    sr_sch_revision_t revision;    /**< Revision of the submodule. */
} sr_sch_submodule_t;

/**
 * @brief Structure that contains information about a module installed in sysrepo.
 */
typedef struct sr_schema_s {
    /**
     * Memory context used internally by Sysrepo for efficient storage
     * and conversion of this structure.
     */
    sr_mem_ctx_t *_sr_mem;

    const char *module_name;         /**< Name of the module. */
    const char *ns;                  /**< Namespace of the module used in @ref xp_page "XPath". */
    const char *prefix;              /**< Prefix of the module. */
    bool installed;                  /**< TRUE if the module was explicitly installed. */
    bool implemented;                /**< TRUE if the module is implemented (does not have to be installed),
                                          not just imported. */

    sr_sch_revision_t revision;      /**< Revision the module. */

    sr_sch_submodule_t *submodules;  /**< Array of all installed submodules of the module. */
    size_t submodule_count;          /**< Number of module's submodules. */

    char **enabled_features;         /**< Array of enabled features */
    size_t enabled_feature_cnt;      /**< Number of enabled feature */
} sr_schema_t;

/**
 * @brief Format types of ::sr_get_schema result
 */
typedef enum sr_schema_format_e {
    SR_SCHEMA_YANG,                         /**< YANG format */
    SR_SCHEMA_YIN                           /**< YIN format */
} sr_schema_format_t;

/**
 * @brief Iterator used for accessing data nodes via ::sr_get_items_iter call.
 */
typedef struct sr_val_iter_s sr_val_iter_t;

/**
 * @brief Retrieves list of schemas installed in the sysrepo datastore.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[out] schemas Array of installed schemas information (allocated by
 * the function, it is supposed to be freed by caller using ::sr_free_schemas call).
 * @param[out] schema_cnt Number of schemas returned in the array.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_list_schemas(sr_session_ctx_t *session, sr_schema_t **schemas, size_t *schema_cnt);

/**
 * @brief Retrieves the content of specified schema file. If the module
 * can not be found SR_ERR_NOT_FOUND is returned.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] module_name Name of the requested module.
 * @param[in] revision Requested revision of the module. If NULL
 * is passed, the latest revision will be returned.
 * @param[in] submodule_name Name of the requested submodule. Pass NULL if you are
 * requesting the content of the main module.
 * @param[in] format of the returned schema
 * @param[out] schema_content Content of the specified schema file. Automatically
 * allocated by the function, should be freed by the caller.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_schema(sr_session_ctx_t *session, const char *module_name, const char *revision,
         const char *submodule_name, sr_schema_format_t format, char **schema_content);

/**
 * @brief Retrieves the content of the specified submodule schema file. If the submodule
 * cannot be found, SR_ERR_NOT_FOUND is returned.
 *
 * @param[in] session Session context acquired from ::sr_session_start call.
 * @param[in] submodule_name Name of the requested submodule.
 * @param[in] submodule_revision Requested revision of the submodule. If NULL
 * is passed, the latest revision will be returned.
 * @param[in] format of the returned schema.
 * @param[out] schema_content Content of the specified schema file. Automatically
 * allocated by the function, should be freed by the caller.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_submodule_schema(sr_session_ctx_t *session, const char *submodule_name, const char *submodule_revision,
                            sr_schema_format_t format, char **schema_content);

/**
 * @brief Retrieves a single data element stored under provided XPath. If multiple
 * nodes matches the xpath SR_ERR_INVAL_ARG is returned.
 *
 * If the xpath identifies an empty leaf, a list or a container, the value
 * has no data filled in and its type is set properly (SR_LEAF_EMPTY_T / SR_LIST_T / SR_CONTAINER_T / SR_CONTAINER_PRESENCE_T).
 *
 * @see @ref xp_page "Path Addressing" documentation, or
 * https://tools.ietf.org/html/draft-ietf-netmod-yang-json#section-6.11
 * for XPath syntax used for identification of yang nodes in sysrepo calls.
 *
 * @see Use ::sr_get_items or ::sr_get_items_iter for retrieving larger chunks
 * of data from the datastore. Since they retrieve the data from datastore in
 * larger chunks, they can work much more efficiently than multiple ::sr_get_item calls.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element to be retrieved.
 * @param[out] value Structure containing information about requested element
 * (allocated by the function, it is supposed to be freed by the caller using ::sr_free_val).
 *
 * @return Error code (SR_ERR_OK on success)
 */
int sr_get_item(sr_session_ctx_t *session, const char *xpath, sr_val_t **value);

/**
 * @brief Retrieves an array of data elements matching provided XPath
 *
 * All data elements are transferred within one message from the datastore,
 * which is much more efficient that calling multiple ::sr_get_item calls.
 *
 * If the user does not have read permission to access certain nodes, these
 * won't be part of the result. SR_ERR_NOT_FOUND will be returned if there are
 * no nodes matching xpath in the data tree, or the user does not have read permission to access them.
 *
 * If the response contains too many elements time out may be exceeded, SR_ERR_TIME_OUT
 * will be returned, use ::sr_get_items_iter.
 *
 * @see @ref xp_page "Path Addressing" documentation
 * for Path syntax used for identification of yang nodes in sysrepo calls.
 *
 * @see ::sr_get_items_iter can be used for the same purpose as ::sr_get_items
 * call if you expect that ::sr_get_items could return too large data sets.
 * Since ::sr_get_items_iter also retrieves the data from datastore in larger chunks,
 * in can still work very efficiently for large datasets.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element to be retrieved.
 * @param[out] values Array of structures containing information about requested data elements
 * (allocated by the function, it is supposed to be freed by the caller using ::sr_free_values).
 * @param[out] value_cnt Number of returned elements in the values array.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_items(sr_session_ctx_t *session, const char *xpath, sr_val_t **values, size_t *value_cnt);

/**
 * @brief Creates an iterator for retrieving of the data elements stored under provided xpath.
 *
 * Requested data elements are transferred from the datastore in larger chunks
 * of pre-defined size, which is much more efficient that calling multiple
 * ::sr_get_item calls, and may be less memory demanding than calling ::sr_get_items
 * on very large datasets.
 *
 * @see @ref xp_page "Path Addressing" documentation, or
 * https://tools.ietf.org/html/draft-ietf-netmod-yang-json#section-6.11
 * for XPath syntax used for identification of yang nodes in sysrepo calls.
 *
 * @see ::sr_get_item_next for iterating over returned data elements.
 * @note Iterator allows to iterate through the values once. To start iteration
 *  from the beginning new iterator must be created.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element / subtree to be retrieved.
 * @param[out] iter Iterator context that can be used to retrieve individual data
 * elements via ::sr_get_item_next calls. Allocated by the function, should be
 * freed with ::sr_free_val_iter.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_items_iter(sr_session_ctx_t *session, const char *xpath, sr_val_iter_t **iter);

/**
 * @brief Returns the next item from the dataset of provided iterator created
 * by ::sr_get_items_iter call. If there is no item left SR_ERR_NOT_FOUND is returned.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in,out] iter Iterator acquired with ::sr_get_items_iter call.
 * @param[out] value Structure containing information about requested element
 * (allocated by the function, it is supposed to be freed by the caller using ::sr_free_val).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_item_next(sr_session_ctx_t *session, sr_val_iter_t *iter, sr_val_t **value);

/**
 * @brief Flags used to customize the behaviour of ::sr_get_subtree and ::sr_get_subtrees calls.
 */
typedef enum sr_get_subtree_flag_e {
    /**
     * Default get-subtree(s) behaviour.
     * All matched subtrees are sent with all their content in one message.
     */
    SR_GET_SUBTREE_DEFAULT = 0,

    /**
     * The iterative get-subtree(s) behaviour.
     * The matched subtrees are sent in chunks and only as needed while they are iterated
     * through using functions ::sr_node_get_child, ::sr_node_get_next_sibling and
     * ::sr_node_get_parent from "sysrepo/trees.h". This behaviour gives much better
     * performance than the default one if only a small portion of matched subtree(s) is
     * actually iterated through.
     * @note It is considered a programming error to access \p next, \p prev, \p parent,
     * \p first_child and \p last_child data members of ::sr_node_t on a partially loaded tree.
     */
    SR_GET_SUBTREE_ITERATIVE = 1
} sr_get_subtree_flag_t;

/**
 * @brief Options for get-subtree and get-subtrees operations.
 * It is supposed to be bitwise OR-ed value of any ::sr_get_subtree_flag_t flags.
 */
typedef uint32_t sr_get_subtree_options_t;

/**
 * @brief Retrieves a single subtree whose root node is stored under the provided XPath.
 * If multiple nodes matches the xpath SR_ERR_INVAL_ARG is returned.
 *
 * The functions returns values and all associated information stored under the root node and
 * all its descendants. While the same data can be obtained using ::sr_get_items in combination
 * with the expressive power of XPath addressing, the recursive nature of the output data type
 * also preserves the hierarchical relationships between data elements.
 *
 * Values of internal nodes of the subtree have no data filled in and their type is set properly
 * (SR_LIST_T / SR_CONTAINER_T / SR_CONTAINER_PRESENCE_T), whereas leaf nodes are carrying actual
 * data (apart from SR_LEAF_EMPTY_T).
 *
 * @see @ref xp_page "Path Addressing" documentation
 * for XPath syntax used for identification of yang nodes in sysrepo calls.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier referencing the root node of the subtree to be retrieved.
 * @param[in] opts Options overriding default behavior of this operation.
 * @param[out] subtree Nested structure storing all data of the requested subtree
 * (allocated by the function, it is supposed to be freed by the caller using ::sr_free_tree).
 *
 * @return Error code (SR_ERR_OK on success)
 */
int sr_get_subtree(sr_session_ctx_t *session, const char *xpath, sr_get_subtree_options_t opts,
        sr_node_t **subtree);

/**
 * @brief Retrieves an array of subtrees whose root nodes match the provided XPath.
 *
 * If the user does not have read permission to access certain nodes, these together with
 * their descendants won't be part of the result. SR_ERR_NOT_FOUND will be returned if there are
 * no nodes matching xpath in the data tree, or the user does not have read permission to access them.
 *
 * Subtrees that match the provided XPath are not merged even if they overlap. This significantly
 * simplifies the implementation and decreases the cost of this operation. The downside is that
 * the user must choose the XPath carefully. If the subtree selection process results in too many
 * node overlaps, the cost of the operation may easily outshine the benefits. As an example,
 * a common XPath expression "//." is normally used to select all nodes in a data tree, but for this
 * operation it would result in an excessive duplication of transfered data elements.
 * Since you get all the descendants of each matched node implicitly, you probably should not need
 * to use XPath wildcards deeper than on the top-level.
 * (i.e. "/." is preferred alternative to "//." for get-subtrees operation).
 *
 * If the response contains too many elements time out may be exceeded, SR_ERR_TIME_OUT
 * will be returned.
 *
 * @see @ref xp_page "Path Addressing" documentation, or
 * https://tools.ietf.org/html/draft-ietf-netmod-yang-json#section-6.11
 * for XPath syntax used for identification of yang nodes in sysrepo calls.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier referencing root nodes of subtrees to be retrieved.
 * @param[in] opts Options overriding default behavior of this operation.
 * @param[out] subtrees Array of nested structures storing all data of the requested subtrees
 * (allocated by the function, it is supposed to be freed by the caller using ::sr_free_trees).
 * @param[out] subtree_cnt Number of returned trees in the subtrees array.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_subtrees(sr_session_ctx_t *session, const char *xpath, sr_get_subtree_options_t opts,
        sr_node_t **subtrees, size_t *subtree_cnt);


////////////////////////////////////////////////////////////////////////////////
// Data Manipulation API (edit-config functionality)
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Flags used to override default behavior of data manipulation calls.
 */
typedef enum sr_edit_flag_e {
    SR_EDIT_DEFAULT = 0,        /**< Default behavior - recursive and non-strict. */
    SR_EDIT_NON_RECURSIVE = 1,  /**< Non-recursive behavior:
                                     by ::sr_set_item, all preceding nodes (parents) of the identified element must exist,
                                     by ::sr_delete_item xpath must not identify an non-empty list or non-empty container. */
    SR_EDIT_STRICT = 2          /**< Strict behavior:
                                     by ::sr_set_item the identified element must not exist (similar to netconf create operation),
                                     by ::sr_delete_item the identified element must exist (similar to netconf delete operation). */
} sr_edit_flag_t;

/**
 * @brief Options overriding default behavior of data manipulation calls,
 * it is supposed to be bitwise OR-ed value of any ::sr_edit_flag_t flags.
 */
typedef uint32_t sr_edit_options_t;

/**
 * @brief Options for specifying move direction of ::sr_move_item call.
 */
typedef enum sr_move_position_e {
    SR_MOVE_BEFORE = 0,    /**< Move the specified item before the selected sibling. */
    SR_MOVE_AFTER = 1,     /**< Move the specified item after the selected. */
    SR_MOVE_FIRST = 2,     /**< Move the specified item to the position of the first child. */
    SR_MOVE_LAST = 3,      /**< Move the specified item to the position of the last child. */
} sr_move_position_t;

/**
 * @brief Sets the value of the leaf, leaf-list, list or presence container.
 *
 * With default options it recursively creates all missing nodes (containers and
 * lists including their key leaves) in the xpath to the specified node (can be
 * turned off with SR_EDIT_NON_RECURSIVE option). If SR_EDIT_STRICT flag is set,
 * the node must not exist (otherwise an error is returned).
 *
 * To create a list use xpath with key values included and pass NULL as value argument.
 *
 * Setting of a leaf-list value appends the value at the end of the leaf-list.
 * A value of leaf-list can be specified either by predicate in xpath or by value argument.
 * If both are present, value argument is ignored and xpath predicate is used.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element to be set.
 * @param[in] value Value to be set on specified xpath. xpath member of the
 * ::sr_val_t structure can be NULL. Value will be copied - can be allocated on stack.
 * @param[in] opts Options overriding default behavior of this call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_set_item(sr_session_ctx_t *session, const char *xpath, const sr_val_t *value, const sr_edit_options_t opts);


/**
 * @brief Functions is similar to ::sr_set_item with the difference that the value to be set
 * is provided as string.
 * @param [in] session Session context acquired with ::sr_session_start call.
 * @param [in] xpath @ref xp_page "Data Path" identifier of the data element to be set.
 * @param [in] value string representation of the value to be set
 * @param [in] opts same as for ::sr_set_item
 * @return Error code (SR_ERR_OK on success).
 */
int sr_set_item_str(sr_session_ctx_t *session, const char *xpath, const char *value, const sr_edit_options_t opts);
/**
 * @brief Deletes the nodes under the specified xpath.
 *
 * To delete non-empty lists or containers SR_EDIT_NON_RECURSIVE flag must not be set.
 * If SR_EDIT_STRICT flag is set the specified node must must exist in the datastore.
 * If the xpath includes the list keys, the specified list instance is deleted.
 * If the xpath to list does not include keys, all instances of the list are deleted.
 * SR_ERR_UNAUTHORIZED will be returned if the user does not have write permission to any affected node.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element to be deleted.
 * @param[in] opts Options overriding default behavior of this call.
 *
 * @return Error code (SR_ERR_OK on success).
 **/
int sr_delete_item(sr_session_ctx_t *session, const char *xpath, const sr_edit_options_t opts);

/**
 * @brief Move the instance of an user-ordered list or leaf-list to the specified position.
 *
 * Item can be move to the first or last position or positioned relatively to its sibling.
 * @note To determine current order, you can issue a ::sr_get_items call
 * (without specifying keys of the list in question).
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the data element to be moved.
 * @param[in] position Requested move direction.
 * @param[in] relative_item xpath Identifier of the data element that is used
 * to determine relative position, used only if position argument is SR_MOVE_BEFORE or SR_MOVE_AFTER.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_move_item(sr_session_ctx_t *session, const char *xpath, const sr_move_position_t position, const char *relative_item);

/**
 * @brief Perform the validation of changes made in current session, but do not
 * commit nor discard them.
 *
 * Provides only YANG validation, commit verify subscribers won't be notified in this case.
 *
 * @see Use ::sr_get_last_errors to retrieve error information if the validation
 * returned with an error.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_validate(sr_session_ctx_t *session);

/**
 * @brief Apply changes made in current session.
 *
 * @note Note that in case that you are committing to the running datstore, you also
 * need to copy the config to startup to make changes permanent after restart.
 *
 * @see Use ::sr_get_last_errors to retrieve error information if the commit
 * operation returned with an error.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_commit(sr_session_ctx_t *session);

/**
 * @brief Discard non-committed changes made in current session.
 *
 * @note Since the function effectively clears all the cached data within the session,
 * the next operation will operate on fresh data loaded from the datastore
 * (i.e. no need to call ::sr_session_refresh afterwards).
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_discard_changes(sr_session_ctx_t *session);

/**
 * @brief Replaces an entire configuration datastore  with the contents of
 * another complete configuration datastore. If the module is specified, limits
 * the copy operation only to one specified module. If it's not specified,
 * the operation is performed on all modules that are currently active in the
 * source datastore.
 *
 * If the target datastore exists, it is overwritten. Otherwise, a new one is created.
 *
 * @note ::sr_session_refresh is needed to see the result of a copy-config operation
 * in a session apart from the case when SR_DS_CANDIDATE is the destination datastore.
 * Since the candidate is not shared among sessions, data trees are copied only to the
 * canidate in the session issuing the copy-config operation.
 *
 * @note Operation may fail, if it tries to copy a not enabled configuration to the
 * running datastore.
 *
 * @note \p session \p dst_datastore uncommitted changes will get discarded.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] module_name If specified, only limits the copy operation only to
 * one specified module.
 * @param[in] src_datastore Source datastore.
 * @param[in] dst_datastore Destination datastore.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_copy_config(sr_session_ctx_t *session, const char *module_name,
        sr_datastore_t src_datastore, sr_datastore_t dst_datastore);


////////////////////////////////////////////////////////////////////////////////
// Locking API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Locks the datastore which the session is tied to. If there is
 * a module locked by the other session SR_ERR_LOCKED is returned.
 * Operation fails if there is a modified data tree in session.
 *
 * All data models within the datastore will be locked for writing until
 * ::sr_unlock_datastore is called or until the session is stopped or terminated
 * for any reason.
 *
 * The lock operation will not be allowed if the user does not have sufficient
 * permissions for writing into each of the data models in the datastore.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_lock_datastore(sr_session_ctx_t *session);

/**
 * @brief Unlocks the datastore which the session is tied to.
 *
 * All data models within the datastore will be unlocked if they were locked
 * by this session.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_unlock_datastore(sr_session_ctx_t *session);

/**
 * @brief Locks specified data module within the datastore which the session
 * is tied to. Operation fails if the data tree has been modified.
 *
 * Specified data module will be locked for writing in the datastore until
 * ::sr_unlock_module is called or until the session is stopped or terminated
 * for any reason.
 *
 * The lock operation will not be allowed if the user does not have sufficient
 * permissions for writing into the specified data module.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] module_name Name of the module to be locked.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_lock_module(sr_session_ctx_t *session, const char *module_name);

/**
 * @brief Unlocks specified data module within the datastore which the session
 * is tied to.
 *
 * Specified data module will be unlocked if was locked in the datastore
 * by this session.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] module_name Name of the module to be unlocked.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_unlock_module(sr_session_ctx_t *session, const char *module_name);


////////////////////////////////////////////////////////////////////////////////
// Change Notifications API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Flags used to override default handling of subscriptions.
 */
typedef enum sr_subscr_flag_e {
    /**
     * @brief Default behavior of the subscription. In case of ::sr_module_change_subscribe and
     * ::sr_subtree_change_subscribe calls it means that:
     *
     * - the subscriber is the "owner" of the subscribed data tree and and the data tree will be enabled in the running
     *   datastore while this subscription is alive (if not already, can be changed using ::SR_SUBSCR_PASSIVE flag),
     * - configuration data of the subscribed module or subtree is copied from startup to running datastore
     *   (only if the module was not enabled before),
     * - the callback will be called twice, once with ::SR_EV_VERIFY event and once with ::SR_EV_APPLY / ::SR_EV_ABORT
     *   event passed in (can be changed with ::SR_SUBSCR_APPLY_ONLY flag).
     */
    SR_SUBSCR_DEFAULT = 0,

    /**
     * @brief This option enables the application to re-use an already existing subscription context previously returned
     * from any sr_*_subscribe call instead of requesting the creation of a new one. In that case a single
     * ::sr_unsubscribe call unsubscribes from all subscriptions filed within the context.
     */
    SR_SUBSCR_CTX_REUSE = 1,

    /**
     * @brief The subscriber is not the "owner" of the subscribed data tree, just a passive watcher for changes.
     * When this option is passed in to ::sr_module_change_subscribe or ::sr_subtree_change_subscribe,
     * the subscription will have no effect on the presence of the subtree in the running datastore.
     */
    SR_SUBSCR_PASSIVE = 2,

    /**
     * @brief The subscriber does not support verification of the changes and wants to be notified only after
     * the changes has been applied in the datastore, without the possibility to deny them
     * (it will receive only ::SR_EV_APPLY events).
     */
    SR_SUBSCR_APPLY_ONLY = 4,

    /**
     * @brief The subscriber wants ::SR_EV_ENABLED notifications to be sent to them.
     */
    SR_SUBSCR_EV_ENABLED = 8,

    /**
     * @brief The subscriber will not receive ::SR_EV_ABORT if he returns an error in verify phase
     * (if the commit is refused by other verifier ::SR_EV_ABORT will be delivered).
     */
    SR_SUBSCR_NO_ABORT_FOR_REFUSED_CFG = 16,

    /**
     * @brief No real-time notifications will be delivered until ::sr_event_notif_replay is called
     * and replay has finished (::SR_EV_NOTIF_T_REPLAY_COMPLETE is delivered).
     */
    SR_SUBSCR_NOTIF_REPLAY_FIRST = 32,
} sr_subscr_flag_t;

/**
 * @brief Type of the notification event that has occurred (passed to notification callbacks).
 *
 * @note Each change is normally notified twice: first as ::SR_EV_VERIFY event and then as ::SR_EV_APPLY or ::SR_EV_ABORT
 * event. If the subscriber does not support verification, it can subscribe only to ::SR_EV_APPLY event by providing
 * ::SR_SUBSCR_APPLY_ONLY subscription flag.
 */
typedef enum sr_notif_event_e {
    SR_EV_VERIFY,  /**< Occurs just before the changes are committed to the datastore,
                        the subscriber is supposed to verify that the changes are valid and can be applied
                        and prepare all resources required for the changes. The subscriber can still deny the changes
                        in this phase by returning an error from the callback. */
    SR_EV_APPLY,   /**< Occurs just after the changes have been successfully committed to the datastore,
                        the subscriber is supposed to apply the changes now, but it cannot deny the changes in this
                        phase anymore (any returned errors are just logged and ignored). */
    SR_EV_ABORT,   /**< Occurs in case that the commit transaction has failed (possibly because one of the verifiers
                        has denied the change / returned an error). The subscriber is supposed to return the managed
                        application to the state before the commit. Any returned errors are just logged and ignored. */
    SR_EV_ENABLED, /**< Occurs just after the subscription. Subscriber gets notified about configuration that was copied
                        from startup to running. This allows to reuse the callback for applying changes made in running to
                        reflect the changes when the configuration is copied from startup to running during subscription process */
} sr_notif_event_t;

/**
 * @brief Type of the operation made on an item, used by changeset retrieval in ::sr_get_change_next.
 */
typedef enum sr_change_oper_e {
    SR_OP_CREATED,   /**< The item has been created by the change. */
    SR_OP_MODIFIED,  /**< The value of the item has been modified by the change. */
    SR_OP_DELETED,   /**< The item has been deleted by the change. */
    SR_OP_MOVED,     /**< The item has been moved in the subtree by the change (applicable for leaf-lists and user-ordered lists). */
} sr_change_oper_t;

/**
 * @brief State of a module as returned by the ::sr_module_install_cb callback.
 */
typedef enum sr_module_state_e {
    SR_MS_UNINSTALLED,  /**< The module is not installed in the sysrepo repository. */
    SR_MS_IMPORTED,     /**< The module has been implicitly installed into the sysrepo repository
                             as it is imported by another implemented/imported module. */
    SR_MS_IMPLEMENTED   /**< The module has been explicitly installed into the sysrepo repository by the user. */
} sr_module_state_t;

/**
 * @brief Sysrepo subscription context returned from sr_*_subscribe calls,
 * it is supposed to be released by the caller using ::sr_unsubscribe call.
 */
typedef struct sr_subscription_ctx_s sr_subscription_ctx_t;

/**
 * @brief Iterator used for retrieval of a changeset using ::sr_get_changes_iter call.
 */
typedef struct sr_change_iter_s sr_change_iter_t;

/**
 * @brief Options overriding default behavior of subscriptions,
 * it is supposed to be a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 */
typedef uint32_t sr_subscr_options_t;

/**
 * @brief Callback to be called by the event of changing any running datastore
 * content within the specified module. Subscribe to it by ::sr_module_change_subscribe call.
 *
 * @param[in] session Automatically-created session that can be used for obtaining changed data
 * (e.g. by ::sr_get_changes_iter call ot ::sr_get_item -like calls). Do not stop this session.
 * @param[in] module_name Name of the module where the change has occurred.
 * @param[in] event Type of the notification event that has occurred.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to
 * ::sr_module_change_subscribe call.
 */
typedef int (*sr_module_change_cb)(sr_session_ctx_t *session, const char *module_name,
        sr_notif_event_t event, void *private_ctx);

/**
 * @brief Callback to be called by the event of changing any running datastore
 * content within the specified subtree. Subscribe to it by ::sr_subtree_change_subscribe call.
 *
 * @param[in] session Automatically-created session that can be used for obtaining changed data
 * (e.g. by ::sr_get_changes_iter call or ::sr_get_item -like calls). Do not stop this session.
 * @param[in] xpath @ref xp_page "Data Path" of the subtree where the change has occurred.
 * @param[in] event Type of the notification event that has occurred.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to
 * ::sr_subtree_change_subscribe call.
 */
typedef int (*sr_subtree_change_cb)(sr_session_ctx_t *session, const char *xpath,
        sr_notif_event_t event, void *private_ctx);

/**
 * @brief Callback to be called by the event of installation / uninstallation
 * of a new module into sysrepo. Subscribe to it by ::sr_module_install_subscribe call.
 *
 * @param[in] module_name Name of the newly installed / uinstalled module.
 * @param[in] revision Revision of the newly installed module (if specified
 * within the YANG model).
 * @param[in] state The new state of the module (uninstalled vs. imported vs. implemented).
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to
 * ::sr_module_install_subscribe call.
 */
typedef void (*sr_module_install_cb)(const char *module_name, const char *revision, sr_module_state_t state,
        void *private_ctx);

/**
 * @brief Callback to be called by the event of enabling / disabling of
 * a YANG feature within a module. Subscribe to it by ::sr_feature_enable_subscribe call.
 *
 * @param[in] module_name Name of the module where the feature has been enabled / disabled.
 * @param[in] feature_name Name of the feature that has been enabled / disabled.
 * @param[in] enabled TRUE if the feature has been enabled, FALSE if disabled.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to
 * ::sr_feature_enable_subscribe call.
 */
typedef void (*sr_feature_enable_cb)(const char *module_name, const char *feature_name, bool enabled, void *private_ctx);

/**
 * @brief Subscribes for notifications about the changes made within specified
 * module in running datastore.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] module_name Name of the module of interest for change notifications.
 * @param[in] callback Callback to be called when the change in the datastore occurs.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] priority Specifies the order in which the callbacks will be called (callbacks with higher
 * priority will be called sooner, callbacks with the priority of 0 will be called at the end).
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_module_change_subscribe(sr_session_ctx_t *session, const char *module_name, sr_module_change_cb callback,
        void *private_ctx, uint32_t priority, sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for notifications about the changes made within specified
 * subtree in running datastore.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the subtree of the interest for change notifications.
 * @param[in] callback Callback to be called when the change in the datastore occurs.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] priority Specifies the order in which the callbacks will be called (callbacks with higher
 * priority will be called sooner, callbacks with the priority of 0 will be called at the end).
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_subtree_change_subscribe(sr_session_ctx_t *session, const char *xpath, sr_subtree_change_cb callback,
        void *private_ctx, uint32_t priority, sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for notifications about installation / uninstallation
 * of a new module into sysrepo.
 *
 * Mainly intended for northbound management applications that need to be
 * always aware of all active modules installed in sysrepo.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] callback Callback to be called when the event occurs.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_module_install_subscribe(sr_session_ctx_t *session, sr_module_install_cb callback, void *private_ctx,
        sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for notifications about enabling / disabling of
 * a YANG feature within a module.
 *
 * Mainly intended for northbound management applications that need to be
 * always aware of all active features within the modules installed in sysrepo.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] callback Callback to be called when the event occurs.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_feature_enable_subscribe(sr_session_ctx_t *session, sr_feature_enable_cb callback, void *private_ctx,
        sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Unsubscribes from a subscription acquired by any of sr_*_subscribe
 * calls and releases all subscription-related data.
 *
 * @note In case that the same subscription context was used to subscribe for
 * multiple subscriptions, unsubscribes from all of them.
 *
 * @param[in] session Session context acquired with ::sr_session_start call. Does not
 * need to be the same as used for subscribing. NULL can be passed too, in that case
 * a temporary session used for unsubscribe will be automatically created by sysrepo.
 * @param[in] subscription Subscription context acquired by any of sr_*_subscribe calls.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_unsubscribe(sr_session_ctx_t *session, sr_subscription_ctx_t *subscription);

/**
 * @brief Creates an iterator for retrieving of the changeset (list of newly
 * added / removed / modified nodes) in notification callbacks.
 *
 * @see ::sr_get_change_next for iterating over the changeset using this iterator.
 *
 * @param[in] session Session context as passed to notication the callbacks (e.g.
 * ::sr_module_change_cb or ::sr_subtree_change_cb). Will not work with any other sessions.
 * @param[in] xpath @ref xp_page "Data Path" identifier of the subtree from which the changeset
 * should be obtained. Only XPaths that would be accepted by ::sr_subtree_change_subscribe are allowed.
 * @param[out] iter Iterator context that can be used to retrieve individual changes using
 * ::sr_get_change_next calls. Allocated by the function, should be freed with ::sr_free_change_iter.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_changes_iter(sr_session_ctx_t *session, const char *xpath, sr_change_iter_t **iter);

/**
 * @brief Returns the next change from the changeset of provided iterator created
 * by ::sr_get_changes_iter call. If there is no item left, SR_ERR_NOT_FOUND is returned.
 *
 * @note If the operation is ::SR_OP_MOVED the meaning of new_value and old value argument is
 * as follows - the value pointed by new_value was moved after the old_value. If the
 * old value is NULL it was moved to the first position.
 *
 * @param[in] session Session context as passed to notication the callbacks (e.g.
 * ::sr_module_change_cb or ::sr_subtree_change_cb). Will not work with any other sessions.
 * @param[in,out] iter Iterator acquired with ::sr_get_changes_iter call.
 * @param[out] operation Type of the operation made on the returned item.
 * @param[out] old_value Old value of the item (the value before the change).
 * NULL in case that the item has been just created (operation == SR_OP_CREATED).
 * @param[out] new_value New (modified) value of the the item. NULL in case that
 * the item has been just deleted (operation == SR_OP_DELETED).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_get_change_next(sr_session_ctx_t *session, sr_change_iter_t *iter, sr_change_oper_t *operation,
        sr_val_t **old_value, sr_val_t **new_value);


////////////////////////////////////////////////////////////////////////////////
// RPC (Remote Procedure Calls) API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Check if the owner of this session is authorized by NACM to invoke the protocol
 * operation defined in a (installed) YANG module under the given xpath (as RPC or Action).
 *
 * This call is intended for northbound management applications that need to implement
 * the NETCONF Access Control Model (RFC 6536) to restrict the protocol operations that
 * each user is authorized to execute.
 *
 * NETCONF access control is already included in the processing of ::sr_rpc_send,
 * ::sr_rpc_send_tree, ::sr_action_send and ::sr_action_send_tree and thus it should be
 * sufficient to call this function only prior to executing any of the NETCONF standard
 * protocol operations as they cannot be always directly translated to a single sysrepo
 * API call.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the protocol operation.
 * @param[out] permitted TRUE if the user is permitted to execute the given operation, FALSE otherwise.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_check_exec_permission(sr_session_ctx_t *session, const char *xpath, bool *permitted);

/**
 * @brief Callback to be called by the delivery of RPC specified by xpath.
 * Subscribe to it by ::sr_rpc_subscribe call.
 *
 * @param[in] xpath @ref xp_page "Data Path" identifying the RPC.
 * @param[in] input Array of input parameters.
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters. Should be allocated on heap,
 * will be freed by sysrepo after sending of the RPC response.
 * @param[out] output_cnt Number of output parameters.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to ::sr_rpc_subscribe call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
typedef int (*sr_rpc_cb)(const char *xpath, const sr_val_t *input, const size_t input_cnt,
        sr_val_t **output, size_t *output_cnt, void *private_ctx);

/**
 * @brief Callback to be called by the delivery of RPC specified by xpath.
 * This RPC callback variant operates with sysrepo trees rather than with sysrepo values,
 * use it with ::sr_rpc_subscribe_tree and ::sr_rpc_send_tree.
 *
 * @param[in] xpath @ref xp_page "Data Path" identifying the RPC.
 * @param[in] input Array of input parameters (represented as trees).
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters (represented as trees). Should be allocated on heap,
 * will be freed by sysrepo after sending of the RPC response.
 * @param[out] output_cnt Number of output parameters.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to ::sr_rpc_subscribe_tree call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
typedef int (*sr_rpc_tree_cb)(const char *xpath, const sr_node_t *input, const size_t input_cnt,
        sr_node_t **output, size_t *output_cnt, void *private_ctx);

/**
 * @brief Subscribes for delivery of RPC specified by xpath.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying the RPC.
 * @param[in] callback Callback to be called when the RPC is called.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_rpc_subscribe(sr_session_ctx_t *session, const char *xpath, sr_rpc_cb callback, void *private_ctx,
        sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for delivery of RPC specified by xpath. Unlike ::sr_rpc_subscribe, this
 * function expects callback of type ::sr_rpc_tree_cb, therefore use this version if you prefer
 * to manipulate with RPC input and output data organized in a list of trees rather than as a flat
 * enumeration of all values.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying the RPC.
 * @param[in] callback Callback to be called when the RPC is called.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_rpc_subscribe_tree(sr_session_ctx_t *session, const char *xpath, sr_rpc_tree_cb callback,
        void *private_ctx, sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Sends a RPC specified by xpath and waits for the result.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the RPC.
 * @param[in] input Array of input parameters (array of all nodes that hold some
 * data in RPC input subtree - same as ::sr_get_items would return).
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters (all nodes that hold some data
 * in RPC output subtree). Will be allocated by sysrepo and should be freed by
 * caller using ::sr_free_values.
 * @param[out] output_cnt Number of output parameters.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_rpc_send(sr_session_ctx_t *session, const char *xpath,
        const sr_val_t *input,  const size_t input_cnt, sr_val_t **output, size_t *output_cnt);

/**
 * @brief Sends a RPC specified by xpath and waits for the result. Input and output data
 * are represented as arrays of subtrees reflecting the scheme of RPC arguments.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the RPC.
 * @param[in] input Array of input parameters (organized in trees).
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters (organized in trees).
 * Will be allocated by sysrepo and should be freed by caller using ::sr_free_trees.
 * @param[out] output_cnt Number of output parameters.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_rpc_send_tree(sr_session_ctx_t *session, const char *xpath,
        const sr_node_t *input,  const size_t input_cnt, sr_node_t **output, size_t *output_cnt);


////////////////////////////////////////////////////////////////////////////////
// Action API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Callback to be called by the delivery of Action (operation connected to a specific data node)
 * specified by xpath. Subscribe to it by ::sr_action_subscribe call.
 * @see This type is an alias for @ref sr_rpc_cb "the RPC callback type"
 */
typedef sr_rpc_cb sr_action_cb;

/**
 * @brief Callback to be called by the delivery of Action (operation connected to a specific data node)
 * specified by xpath.
 * This callback variant operates with sysrepo trees rather than with sysrepo values,
 * use it with ::sr_action_subscribe_tree and ::sr_action_send_tree.
 * @see This type is an alias for tree variant of @ref sr_rpc_tree_cb "the RPC callback "
 */
typedef sr_rpc_tree_cb sr_action_tree_cb;

/**
 * @brief Subscribes for delivery of Action specified by xpath.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying the Action.
 * @param[in] callback Callback to be called when the Action is called.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_action_subscribe(sr_session_ctx_t *session, const char *xpath, sr_action_cb callback, void *private_ctx,
        sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for delivery of Action specified by xpath. Unlike ::sr_action_subscribe, this
 * function expects callback of type ::sr_action_tree_cb, therefore use this version if you prefer
 * to manipulate with Action input and output data organized in a list of trees rather than as a flat
 * enumeration of all values.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying the Action.
 * @param[in] callback Callback to be called when the Action is called.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_action_subscribe_tree(sr_session_ctx_t *session, const char *xpath, sr_action_tree_cb callback,
        void *private_ctx, sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);

/**
 * @brief Executes an action specified by xpath and waits for the result.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the Action.
 * @param[in] input Array of input parameters (array of all nodes that hold some
 * data in Action input subtree - same as ::sr_get_items would return).
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters (all nodes that hold some data
 * in Action output subtree). Will be allocated by sysrepo and should be freed by
 * caller using ::sr_free_values.
 * @param[out] output_cnt Number of output parameters.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_action_send(sr_session_ctx_t *session, const char *xpath,
        const sr_val_t *input,  const size_t input_cnt, sr_val_t **output, size_t *output_cnt);

/**
 * @brief Executes an action specified by xpath and waits for the result. Input and output data
 * are represented as arrays of subtrees reflecting the scheme of Action arguments.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the Action.
 * @param[in] input Array of input parameters (organized in trees).
 * @param[in] input_cnt Number of input parameters.
 * @param[out] output Array of output parameters (organized in trees).
 * Will be allocated by sysrepo and should be freed by caller using ::sr_free_trees.
 * @param[out] output_cnt Number of output parameters.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_action_send_tree(sr_session_ctx_t *session, const char *xpath,
        const sr_node_t *input,  const size_t input_cnt, sr_node_t **output, size_t *output_cnt);


////////////////////////////////////////////////////////////////////////////////
// Event Notifications API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Type of the notification passed to the ::sr_event_notif_cb and ::sr_event_notif_tree_cb callbacks.
 */
typedef enum sr_ev_notif_type_e {
    SR_EV_NOTIF_T_REALTIME,         /**< Real-time notification. The only possible type if you don't use ::sr_event_notif_replay. */
    SR_EV_NOTIF_T_REPLAY,           /**< Replayed notification. */
    SR_EV_NOTIF_T_REPLAY_COMPLETE,  /**< Not a real notification, just a signal that the notification replay has completed
                                         (all the stored notifications from the given time interval have been delivered). */
    SR_EV_NOTIF_T_REPLAY_STOP,      /**< Not a real notification, just a signal that replay stop time has been reached
                                         (delivered only if stop_time was specified to ::sr_event_notif_replay). */
} sr_ev_notif_type_t;

/**
 * @brief Flags used to override default notification handling i the datastore.
 */
typedef enum sr_ev_notif_flag_e {
    SR_EV_NOTIF_DEFAULT = 0,      /**< Notification will be handled normally. */
    SR_EV_NOTIF_EPHEMERAL = 1,    /**< Notification will not be stored in the notification store
                                       (and therefore will be also delivered faster). */
} sr_ev_notif_flag_t;

/**
 * @brief Callback to be called by the delivery of event notification specified by xpath.
 * Subscribe to it by ::sr_event_notif_subscribe call.
 *
 * @param[in] notif_type Type of the notification.
 * @param[in] xpath @ref xp_page "Data Path" identifying the event notification.
 * @param[in] values Array of all nodes that hold some data in event notification subtree.
 * @param[in] values_cnt Number of items inside the values array.
 * @param[in] timestamp Time when the notification was generated
 * @param[in] private_ctx Private context opaque to sysrepo,
 * as passed to ::sr_event_notif_subscribe call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
typedef void (*sr_event_notif_cb)(const sr_ev_notif_type_t notif_type, const char *xpath,
        const sr_val_t *values, const size_t values_cnt, time_t timestamp, void *private_ctx);

/**
 * @brief Callback to be called by the delivery of event notification specified by xpath.
 * This callback variant operates with sysrepo trees rather than with sysrepo values,
 * use it with ::sr_event_notif_subscribe_tree and ::sr_event_notif_send_tree.
 *
 * @param[in] notif_type Type of the notification.
 * @param[in] xpath @ref xp_page "Data Path" identifying the event notification.
 * @param[in] trees Array of subtrees carrying event notification data.
 * @param[in] tree_cnt Number of subtrees with data.
 * @param[in] timestamp Time when the notification was generated
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to ::sr_event_notif_subscribe_tree call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
typedef void (*sr_event_notif_tree_cb)(const sr_ev_notif_type_t notif_type, const char *xpath,
        const sr_node_t *trees, const size_t tree_cnt, time_t timestamp, void *private_ctx);

/**
 * @brief Subscribes for delivery of an event notification specified by xpath.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying one event notification or special
 * path in the form of a module name in which the whole module is subscribed to.
 * @param[in] callback Callback to be called when the event notification is send.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_event_notif_subscribe(sr_session_ctx_t *session, const char *xpath,
        sr_event_notif_cb callback, void *private_ctx, sr_subscr_options_t opts,
        sr_subscription_ctx_t **subscription);

/**
 * @brief Subscribes for delivery of event notification specified by xpath.
 * Unlike ::sr_event_notif_subscribe, this function expects callback of type ::sr_event_notif_tree_cb,
 * therefore use this version if you prefer to manipulate with event notification data organized
 * in a list of trees rather than as a flat enumeration of all values.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Schema Path" identifying one event notification or special
 * path in the form of a module name in which the whole module is subscribed to.
 * @param[in] callback Callback to be called when the event notification is called.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 * @note An existing context may be passed in case that SR_SUBSCR_CTX_REUSE option is specified.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_event_notif_subscribe_tree(sr_session_ctx_t *session, const char *xpath,
        sr_event_notif_tree_cb callback, void *private_ctx, sr_subscr_options_t opts,
        sr_subscription_ctx_t **subscription);

/**
 * @brief Sends an event notification specified by xpath and waits for the result.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the event notification.
 * @param[in] values Array of all nodes that hold some data in event notification subtree
 * (same as ::sr_get_items would return).
 * @param[in] values_cnt Number of items inside the values array.
 * @param[in] opts Options overriding default handling of the notification, it is supposed to be
 * a bitwise OR-ed value of any ::sr_ev_notif_flag_t flags.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_event_notif_send(sr_session_ctx_t *session, const char *xpath, const sr_val_t *values,
        const size_t values_cnt, sr_ev_notif_flag_t opts);

/**
 * @brief Sends an event notification specified by xpath and waits for the result.
 * The notification data are represented as arrays of subtrees reflecting the scheme
 * of the event notification.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the RPC.
 * @param[in] trees Array of subtrees carrying event notification data.
 * @param[in] tree_cnt Number of subtrees with data.
 * @param[in] opts Options overriding default handling of the notification, it is supposed to be
 * a bitwise OR-ed value of any ::sr_ev_notif_flag_t flags.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_event_notif_send_tree(sr_session_ctx_t *session, const char *xpath, const sr_node_t *trees,
        const size_t tree_cnt, sr_ev_notif_flag_t opts);

/**
 * @brief Replays already generated notifications stored in the notification store related to
 * the provided notification subscription (or subscriptions, in case that ::SR_SUBSCR_CTX_REUSE
 * was used). Notification callbacks of the given susbscriptions will be called with the type set to
 * ::SR_EV_NOTIF_T_REPLAY, ::SR_EV_NOTIF_T_REPLAY_COMPLETE or ::SR_EV_NOTIF_T_REPLAY_STOP.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] subscription Session context acquired with ::sr_session_start call.
 * @param[in] start_time Starting time of the desired time window for notification replay.
 * @param[in] stop_time End time of the desired time window for notification replay. If set to 0,
 * no stop time will be applied (all notifications up to the current time will be delivered,
 * ::SR_EV_NOTIF_T_REPLAY_STOP notification won't be delivered).
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_event_notif_replay(sr_session_ctx_t *session, sr_subscription_ctx_t *subscription,
        time_t start_time, time_t stop_time);


////////////////////////////////////////////////////////////////////////////////
// Operational Data API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Callback to be called when operational data at the selected level is requested.
 * Subscribe to it by ::sr_dp_get_items_subscribe call.
 *
 * Callback handler is supposed to provide data of all nodes at the level selected by the xpath argument:
 *
 * - If the xpath identifies a container, the provider is supposed to return all leaves and leaf-lists values within it.
 * Nested lists and containers should not be provided - sysrepo will ask for them in subsequent calls.
 * - If the xpath identifies a list, the provider is supposed to return all leaves (except for keys!) and
 * leaf-lists values within all instances of the list. Nested lists and containers should not be provided - sysrepo
 * will ask for them in subsequent calls.
 * - If the xpath identifies a leaf-list, the provider is supposed to return all leaf-list values.
 * - If the xpath identifies a leaf, the provider is supposed to return just the leaf in question.
 *
 * The xpath argument passed to callback can be only the xpath that was used for the subscription, or xpath of
 * any nested lists or containers.
 *
 * @param[in] xpath @ref xp_page "Data Path" identifying the level under which the nodes are requested.
 * @param[out] values Array of values at the selected level (allocated by the provider).
 * @param[out] values_cnt Number of values returned.
 * @param[in] request_id An ID identifying the originating request.
 * @param[in] private_ctx Private context opaque to sysrepo, as passed to ::sr_dp_get_items_subscribe call.
 *
 * @return Error code (SR_ERR_OK on success).
 */
typedef int (*sr_dp_get_items_cb)(const char *xpath, sr_val_t **values, size_t *values_cnt, uint64_t request_id, void *private_ctx);

/**
 * @brief Registers for providing of operational data under given xpath.
 *
 * @note The XPath must be generic - must not include any list key values.
 * @note This API works only for operational data (subtrees marked in YANG as "config false").
 * Subscribing as a data provider for configuration data does not have any effect.
 *
 * @param[in] session Session context acquired with ::sr_session_start call.
 * @param[in] xpath @ref xp_page "Data Path" identifying the subtree under which the provider is able to provide
 * operational data.
 * @param[in] callback Callback to be called when the operational data nder given xpat is needed.
 * @param[in] private_ctx Private context passed to the callback function, opaque to sysrepo.
 * @param[in] opts Options overriding default behavior of the subscription, it is supposed to be
 * a bitwise OR-ed value of any ::sr_subscr_flag_t flags.
 * @param[in,out] subscription Subscription context that is supposed to be released by ::sr_unsubscribe.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_dp_get_items_subscribe(sr_session_ctx_t *session, const char *xpath, sr_dp_get_items_cb callback, void *private_ctx,
        sr_subscr_options_t opts, sr_subscription_ctx_t **subscription);


////////////////////////////////////////////////////////////////////////////////
// Application-local File Descriptor Watcher API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Event that has occurred on a monitored file descriptor.
 */
typedef enum sr_fd_event_e {
    SR_FD_INPUT_READY = 1,   /**< File descriptor is now readable without blocking. */
    SR_FD_OUTPUT_READY = 2,  /**< File descriptor is now writable without blocking. */
} sr_fd_event_t;

/**
 * @brief Action that needs to be taken on a file descriptor.
 */
typedef enum sr_fd_action_s {
    SR_FD_START_WATCHING,  /**< Start watching for the specified event on the file descriptor. */
    SR_FD_STOP_WATCHING,   /**< Stop watching for the specified event on the file descriptor. */
} sr_fd_action_t;

/**
 * @brief Structure representing a change in the set of file descriptors monitored by the application.
 */
typedef struct sr_fd_change_s {
    int fd;                 /**< File descriptor whose monitored state should be changed. */
    int events;             /**< Monitoring events tied to the change (or-ed value of ::sr_fd_event_t). */
    sr_fd_action_t action;  /**< Action that is supposed to be performed by application-local file descriptor watcher. */
} sr_fd_change_t;

/**
 * @brief Callback when the subscription manager is terminated
 */
typedef void (*sr_fd_sm_terminated_cb)();

/**
 * @brief Initializes application-local file descriptor watcher.
 *
 * This can be used in those applications that subscribe for changes or providing data in sysrepo, which have their
 * own event loop that is capable of monitoring of the events on provided file descriptors. In case that the
 * application-local file descriptor watcher is initialized, sysrepo client library won't use a separate thread
 * for the delivery of the notifications and for calling the callbacks - they will be called from the main thread of the
 * application's event loop (inside of ::sr_fd_event_process calls).
 *
 * @note Calling this function has global consequences on the behavior of the sysrepo client library within the process
 * that called it. It is supposed to be called as the first sysrepo API call within the application.
 *
 * @param[out] fd Initial file descriptor that is supposed to be monitored for readable events by the application.
 * Once there is an event detected on this file descriptor, the application is supposed to call ::sr_fd_event_process.
 *
 * @param[in] sm_terminate_cb Function to be called when the subscription manager is terminated. If this callback is provided,
 * it shall block until all pending events on any file descriptor associated with sysrepo have been handled. I.e., ensure that
 * the event loop has called sr_fd_event_process() for all pending events before returning from this callback. If this callback
 * doesn't block, errors will be shown in the log.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_fd_watcher_init(int *fd, sr_fd_sm_terminated_cb sm_terminate_cb);

/**
 * @brief Cleans-up the application-local file descriptor watcher previously initiated by ::sr_fd_watcher_init.
 * It is supposed to be called as the last sysrepo API within the application.
 */
void sr_fd_watcher_cleanup();

/**
 * @brief Processes an event that has occurred on one of the file descriptors that the application is monitoring for
 * sysrepo client library purposes. As a result of this event, another file descriptors may need to be started or
 * stopped monitoring by the application. These are returned as \p fd_change_set array.
 *
 * @param[in] fd File descriptor where an event occurred.
 * @param[in] event Type of the event that occurred on the given file descriptor.
 * @param[out] fd_change_set Array of file descriptors that need to be started or stopped monitoring for specified event
 * by the application. The application is supposed to free this array after it processes it.
 * @param[out] fd_change_set_cnt Count of the items in the \p fd_change_set array.
 *
 * @return Error code (SR_ERR_OK on success).
 */
int sr_fd_event_process(int fd, sr_fd_event_t event, sr_fd_change_t **fd_change_set, size_t *fd_change_set_cnt);


////////////////////////////////////////////////////////////////////////////////
// Cleanup Routines
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Frees ::sr_val_t structure and all memory allocated within it.
 *
 * @param[in] value Value to be freed.
 */
void sr_free_val(sr_val_t *value);

/**
 * @brief Frees array of ::sr_val_t structures (and all memory allocated
 * within of each array element).
 *
 * @param[in] values Array of values to be freed.
 * @param[in] count Number of elements stored in the array.
 */
void sr_free_values(sr_val_t *values, size_t count);

/**
 * @brief Frees ::sr_val_iter_t iterator and all memory allocated within it.
 *
 * @param[in] iter Iterator to be freed.
 */
void sr_free_val_iter(sr_val_iter_t *iter);

/**
 * @brief Frees ::sr_change_iter_t iterator and all memory allocated within it.
 *
 * @param[in] iter Iterator to be freed.
 */
void sr_free_change_iter(sr_change_iter_t *iter);

/**
 * @brief Frees array of ::sr_schema_t structures (and all memory allocated
 * within of each array element).
 *
 * @param [in] schemas Array of schemas to be freed.
 * @param [in] count Number of elements stored in the array.
 */
void sr_free_schemas(sr_schema_t *schemas, size_t count);

/**
 * @brief Frees sysrepo tree data.
 *
 * @param[in] tree Tree data to be freed.
 */
void sr_free_tree(sr_node_t *tree);

/**
 * @brief Frees array of sysrepo trees. For each tree, the ::sr_free_tree is called too.
 *
 * @param[in] trees
 * @param[in] count length of array
 */
void sr_free_trees(sr_node_t *trees, size_t count);

/**@} cl */

#ifdef __cplusplus
}
#endif

#endif /* SYSREPO_H_ */