/**
 * @file sysreo.proto
 * @author Rastislav Szabo <raszabo@cisco.com>, Lukas Macko <lmacko@cisco.com>,
 *         Milan Lenco <milan.lenco@pantheon.tech>
 * @brief Definition of sysrepo GPB messages used as the API for the
 * communication between sysrepo engine and sysrepo client library.
 *
 * @copyright
 * Copyright 2016 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.
 */

syntax="proto2";
package sr;

/**
 * @brief Value of an item stored (or to be stored) in the datastore.
 * Can be mapped to sr_val_t data structure from sysrepo library API.
 */
message Value {
  enum Types {
    LIST = 1;
    CONTAINER = 2;
    CONTAINER_PRESENCE = 3;
    LEAF_EMPTY = 4;

    BINARY = 10;
    BITS = 11;
    BOOL = 12;
    DECIMAL64 = 13;
    ENUM = 14;
    IDENTITYREF = 15;
    INSTANCEID = 16;
    INT8 = 17;
    INT16 = 18;
    INT32 = 19;
    INT64 = 20;
    STRING = 21;
    UINT8 = 22;
    UINT16 = 23;
    UINT32 = 24;
    UINT64 = 25;
    ANYXML = 26;
    ANYDATA = 27;
  }

  required string xpath = 1;
  required Types type = 2;
  required bool dflt = 3;

  optional string binary_val = 10;
  optional string bits_val = 11;
  optional bool bool_val = 12;
  optional double decimal64_val = 13;
  optional string enum_val = 14;
  optional string identityref_val = 15;
  optional string instanceid_val = 16;
  optional int32 int8_val = 17;
  optional int32 int16_val = 18;
  optional int32 int32_val = 19;
  optional int64 int64_val = 20;
  optional string string_val = 21;
  optional uint32 uint8_val = 22;
  optional uint32 uint16_val = 23;
  optional uint32 uint32_val = 24;
  optional uint64 uint64_val = 25;
  optional string anyxml_val = 26;
  optional string anydata_val = 27;
}

/**
 * @brief Item stored (or to be stored) in the datastore represented as a tree node
 * reflecting module schema. Can be mapped to sr_node_t data structure from sysrepo library API.
 */
message Node {
  required Value value = 1;        /**< Value of the node; member *xpath* is used to store node's name. */
  required string module_name = 2; /**< Name of the module that defines scheme of this node. */
  repeated Node children = 3;      /**< Direct descendands of this node. */
}

/**
 * @brief Error message retuned from the Sysrepo Engine.
 */
message Error {
  optional string message = 1;
  optional string xpath = 2;
}

/**
 * @brief Variant of the API. Currently only values (sr_val_t) vs. trees (sr_node_t).
 */
enum ApiVariant {
  VALUES = 1;
  TREES = 2;
}


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

/**
 * @brief Datastore on which the configuration session will operate.
 */
enum DataStore {
  STARTUP = 1;
  RUNNING = 2;
  CANDIDATE = 3;
}

/**
 * @brief Flags used to override default session handling.
 */
enum SessionFlags {
  SESS_DEFAULT      = 0x00;   /**< Default (normal) session behavior. */
  SESS_CONFIG_ONLY  = 0x01;   /**< Session will process only configuration data (e.g. sysrepo won't
                                   return any state data by ::sr_get_items / ::sr_get_items_iter calls). */
  SESS_ENABLE_NACM  = 0x02;   /**< Enable NETCONF access control for this session. */
  SESS_NOTIFICATION = 0x400;  /**< Notification session (internal type of session). */
}

/**
 * @brief Request for starting a session. Sent by sr_session_start API call.
 */
message SessionStartReq {
  required DataStore datastore = 1;
  optional string user_name = 2;
  required uint32 options = 3;   /**< Bitwise OR of SessionFlags. */
  optional uint32 commit_id = 4; /**< Applicable if SESS_NOTIFICATION was specified. */
}

/**
 * @brief Response to session_start request.
 */
message SessionStartResp {
  required uint32 session_id = 1;
}

/**
 * @brief Request for stopping the session. Sent by sr_session_stop API call.
 */
message SessionStopReq {
  required uint32 session_id = 1;
}

/**
 * @brief Response to session_stop request.
 */
message SessionStopResp {
  required uint32 session_id = 1;
}

/**
 * @brief Refreshes configuration data cached within the session.
 * Sent by sr_session_refresh API call.
 */
message SessionRefreshReq {
}

/**
 * @brief Response to sr_session_refresh request.
 */
message SessionRefreshResp {
  repeated Error errors = 1;
}

/**
 * @brief Checks aliveness and validity of the session & connection tied to it.
 * Sent by sr_session_check API call.
 */
message SessionCheckReq {
}

/**
 * @brief Response to sr_session_check request.
 */
message SessionCheckResp {
  repeated Error errors = 1;
}

/**
 * @brief Changes the datastore to which the session is tied to.
 */
message SessionSwitchDsReq {
  required DataStore datastore = 1;
}

/**
 * @brief Response to sr_session_switch_ds request.
 */
message SessionSwitchDsResp {

}

/**
 * @brief Request for modification of session options.
 */
message SessionSetOptsReq {
  required uint32 options = 1;
}

/**
 * @brief Response to sr_session_set_options.
 */
message SessionSetOptsResp {
}

/**
 * @brief Request to verify version compatibility.
 */
message VersionVerifyReq {
  required string soname = 1;
}

/**
 * @brief Response to version verification.
 */
 message VersionVerifyResp {
   optional string soname = 1;    /**< server-side SONAME version in case of versions incompatibility. */
 }

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

/**
 * @brief Schema revision details.
 */
message SchemaRevision {
  optional string revision = 1;         /**< Latest revision date of the module. */
  optional string file_path_yang = 2;   /**< Absolute path to file where the schema is stored (YANG format). */
  optional string file_path_yin  = 3;   /**< Absolute path to file where the schema is stored (.yin format). */
}

/**
 * @brief Schema submodule information.
 */
message SchemaSubmodule {
  required string submodule_name = 1;       /**< Submodule name */
  required SchemaRevision revision = 2;     /**< Revision of the submodule */
}
/**
 * @brief Information about a schema installed in sysrepo datastore.
 */
message Schema {
  required string module_name = 1;           /**< Name of the module. */
  required string ns = 2;                    /**< Namespace of the module. */
  required string prefix = 3;                /**< Prefix of he module. */
  required bool installed = 4;               /**< TRUE only for explicitly installed modules (those are always implemented). */
  required bool implemented = 5;             /**< TRUE for implemented modules (do not have to be installed if they have augments,
                                                  deviations or are targets for leafrefs of other implemented modules). */

  required SchemaRevision revision = 6;      /**< Revision of the module*/
  repeated SchemaSubmodule submodules = 7;   /**< Submodules */

  repeated string enabled_features = 8;      /**< Features enabled for the module */
}

/**
 * @brief Retrieves an array of schemas installed in the sysrepo datastore.
 * Sent by sr_list_schemas API call.
 */
message ListSchemasReq {
}

/**
 * @brief Response to sr_list_schemas request.
 */
message ListSchemasResp {
  repeated Schema schemas = 1;
}

/**
 * @brief Retrieves the content of specified schema file.
 * Sent by sr_get_schema API call.
 */
message GetSchemaReq {
  optional string module_name = 1;
  optional string revision = 2;
  optional string submodule_name = 3;
  optional string submodule_revision = 4;
  required bool yang_format = 5;
}

/**
 * @brief Response to sr_get_schema request.
 */
message GetSchemaResp {
  required string schema_content = 1;
}

/**
 * @brief Retrieves a single data element stored under provided path.
 * Sent by sr_get_item API call.
 */
message GetItemReq {
  required string xpath = 1;
}

/**
 * @brief Response to get_item request.
 */
message GetItemResp {
  optional Value value = 1;
}

/**
 * @brief Retrieves an array of data elements stored under provided path.
 * Sent by sr_get_items and sr_get_items_iter API calls.
 */
message GetItemsReq {
  required string xpath = 1;

  /*
   * The options below are applicable only for sr_get_items_iter
   * (not set by sr_get_items).
   */
  optional uint32 limit = 2;
  optional uint32 offset = 3;
}

/**
 * @brief Response to get_items / sr_get_items_iter request.
 */
message GetItemsResp {
  repeated Value values = 1;
}

/**
 * @brief Retrieves a single subtree whose root is stored under provided path.
 * Sent by sr_get_subtree API call.
 */
message GetSubtreeReq {
  required string xpath = 1;
}

/**
 * @brief Response to sr_get_subtree request.
 */
message GetSubtreeResp {
  optional Node tree = 1;
}

/**
 * @brief Retrieves an array of subtrees whose root nodes match provided path.
 * Sent by sr_get_subtrees API call.
 */
message GetSubtreesReq {
  required string xpath = 1;
}

/**
 * @brief Response to sr_get_subtrees request.
 */
message GetSubtreesResp {
  repeated Node trees = 1;
}

/**
 * @brief Retrieves a chunk of a single or multiple subtrees.
 * A subtree chunk is also a tree, where the root node is the node referenced by XPath,
 * the next level consists of its children skipping the first "slice_offset" nodes and including
 * at most "slice_limit" nodes, while the remaining (depth_limit-2) levels always start with
 * the first child (slice_offset is ignored) and include at most "child_limit" nodes.
 * The chunk consists of at most "depth_limit" levels.
 * @note Order of child nodes depends on the libyang implementation.
 */
message GetSubtreeChunkReq {
  required string xpath = 1;
  required bool single = 2;
  required uint32 slice_offset = 3;
  required uint32 slice_width = 4;
  required uint32 child_limit = 5;
  required uint32 depth_limit = 6;
}

/**
 * @brief Response to sr_get_subtree_chunk request.
 */
message GetSubtreeChunkResp {
  repeated string xpath = 1; /**< JSON node-id of the root node for each subtree chunk */
  repeated Node chunk = 2;   /**< first chunk may carry mutliple trees */
}

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

/**
 * @brief Flags used to override default behavior of data manipulation calls.
 */
enum EditFlags {
  EDIT_DEFAULT       = 0x00;  /**< Default behavior - recursive and non-strict. */
  EDIT_NON_RECURSIVE = 0x01;  /**< Non-recursive behavior:
                                   by ::SetItemReq, all preceding nodes (parents) of the identified element must exist,
                                   by ::DeleteItemReq xpath must not identify an non-empty list or non-empty container. */
  EDIT_STRICT        = 0x02;  /**< Strict behavior:
                                   by ::SetItemReq the identified element must not exist (similar to netconf create operation),
                                   by ::DeleteItemReq the identified element must exist (similar to netconf delete operation). */
}

/**
 * @brief Sets the value of the leaf, leaf-list or presence container.
 * Sent by sr_set_item API call.
 */
message SetItemReq {
  required string xpath = 1;
  optional Value value = 2;
  required uint32 options = 3;  /**< Bitwise OR of EditFlags */
}

/**
 * @brief Response to sr_set_item request.
 */
message SetItemResp {
}

/**
 * @brief Sets the value of the leaf, leaf-list or presence container.
 * The value is transferred as string.
 * Sent by sr_set_item_str API call.
 */
message SetItemStrReq {
  required string xpath = 1;
  optional string value = 2;
  required uint32 options = 3;  /**< Bitwise OR of EditFlags */
}

/**
 * @brief Response to sr_set_item_str request.
 */
message SetItemStrResp {
}


/**
 * @brief Deletes the nodes under the specified xpath.
 * Sent by sr_delete_item API call.
 */
message DeleteItemReq {
  required string xpath = 1;
  required uint32 options = 3;  /**< Bitwise OR of EditFlags */
}

/**
 * @brief Response to sr_delete_item request.
 */
message DeleteItemResp {
}

/**
 * @brief Move the instance of an ordered list in specified direction.
 * Sent by sr_move_item API call.
 */
message MoveItemReq {
  enum MovePosition {
    BEFORE = 1;
    AFTER = 2;
    FIRST = 3;
    LAST = 4;
  }
  required string xpath = 1;
  required MovePosition position = 2;
  optional string relative_item = 3;
}

/**
 * @brief Response to sr_move_item request.
 */
message MoveItemResp {
}

/**
 * @brief Perform the validation of changes made in current session, but do not
 * commit nor discard them. Sent by sr_validate API call.
 */
message ValidateReq {
}

/**
 * @brief Response to sr_validate request.
 */
message ValidateResp {
  repeated Error errors = 1;
}

/**
 * @brief Apply changes made in current session.
 * Sent by sr_commit API call.
 */
message CommitReq {
}

/**
 * @brief Response to sr_commit request.
 */
message CommitResp {
  repeated Error errors = 1;
}

/**
 * @brief Discard non-committed changes made in current session.
 * Sent by sr_discard_changes API call.
 */
message DiscardChangesReq {
}

/**
 * @brief Response to sr_discard_changes request.
 */
message DiscardChangesResp {
}

/**
 * @brief Replaces an entire configuration datastore  with the contents of
 * another complete configuration datastore. Sent by sr_copy_config request.
 */
message CopyConfigReq {
  required DataStore src_datastore = 1;
  required DataStore dst_datastore = 2;
  optional string module_name = 3;  /**< If not specified, the operation is performed on all
                                         modules that are currently active in the source datastore */
}

/**
 * @brief Response to sr_copy_config request.
 */
message CopyConfigResp {
  repeated Error errors = 1;
}


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

/**
 * @brief Locks specified data model or the datastore which the session is tied to.
 * Sent by sr_lock_datastore and sr_lock_model API calls.
 */
message LockReq {
  optional string module_name = 1;  /**< If module name is not set, LockReq locks whole datastore. */
}

/**
 * @brief Response to sr_lock_datastore or sr_lock_model request.
 */
message LockResp {
}

/**
 * @brief Unlocks specified data model or the datastore which the session is tied to.
 * Sent by sr_unlock_datastore and sr_unlock_model API calls.
 */
message UnlockReq {
  optional string module_name = 1;  /**< If module name is not set, UnlockReq unlocks whole datastore. */
}

/**
 * @brief Response to sr_lock_datastore or sr_lock_model request.
 */
message UnlockResp {
}


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

enum SubscriptionType {
  MODULE_INSTALL_SUBS = 1;
  FEATURE_ENABLE_SUBS = 2;

  MODULE_CHANGE_SUBS = 10;
  SUBTREE_CHANGE_SUBS = 11;

  DP_GET_ITEMS_SUBS = 20;

  RPC_SUBS = 30;
  ACTION_SUBS = 31;

  EVENT_NOTIF_SUBS = 40;

  HELLO_SUBS = 50;           /**< Used only internally to test for inactive notification subscriptions. */
  COMMIT_END_SUBS = 51;      /**< Used only internally to notify about the end of the commit process. */
}

enum NotificationEvent {
  VERIFY_EV = 1;
  APPLY_EV = 2;
  ABORT_EV = 3;
  ENABLED_EV = 4;
}

message SubscribeReq {
  required SubscriptionType type = 1;

  required string destination = 2;
  required uint32 subscription_id = 3;

  optional string module_name = 4;
  optional string xpath = 5;

  optional NotificationEvent notif_event = 10;
  optional uint32 priority = 11;
  optional bool enable_running = 12;
  optional bool enable_event = 13;

  required ApiVariant api_variant = 20;
}

message SubscribeResp {
}

message UnsubscribeReq {
  required SubscriptionType type = 1;

  required string destination = 2;
  required uint32 subscription_id = 3;

  optional string module_name = 4;
}

message UnsubscribeResp {
}

/**
 * @brief Checks whether the module has any enabled subtree.
 * Sent by sr_check_enabled_running.
 */
message CheckEnabledRunningReq {
  required string module_name = 1;
}

message CheckEnabledRunningResp {
  required bool enabled = 1;
}

enum ModuleState {
    UNINSTALLED = 1;
    IMPORTED = 2;
    IMPLEMENTED = 3;
}

message ModuleInstallNotification {
  optional string module_name = 1;
  optional string revision = 2;
  required ModuleState state = 3;
}

message FeatureEnableNotification {
  required string module_name = 1;
  required string feature_name = 2;
  required bool enabled = 3;
}

message ModuleChangeNotification {
  required NotificationEvent event = 1;
  required string module_name = 2;
}

message SubtreeChangeNotification {
  required NotificationEvent event = 1;
  required string xpath = 2;
}

enum ChangeOperation {
   CREATED = 1;
   MODIFIED = 2;
   DELETED = 3;
   MOVED = 4;
}

message Change {
    required ChangeOperation changeOperation = 1;
    optional Value new_value = 2;
    optional Value old_value = 3;
}

/**
 * @brief Retrieves an array of changes made under provided path.
 * Sent by sr_get_changes_iter or sr_get_change_next API calls.
 */
message GetChangesReq {
  required string xpath = 1;
  required uint32 limit = 2;
  required uint32 offset = 3;
}

/**
 * @brief Response to get_changes request.
 */
message GetChangesResp {
  repeated Change changes = 1;
}


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

/**
 * @brief Sends a request to check if the owner of this session is authorized to invoke
 * the protocol operation referenced by the xpath.
 * Sent by sr_check_exec_permission.
 */
message CheckExecPermReq {
    required string xpath = 1;
}

/**
 * @brief Response to sr_check_exec_permission request.
 */
message CheckExecPermResp {
    required bool permitted = 1;
}

/**
 * @brief Sends a RPC / action request into the datastore, will be delivered to the RPC subscriber.
 * Sent by sr_rpc_send / sr_rpc_send_tree and sr_action_send / sr_action_send_tree API calls.
 */
message RPCReq {
  required bool action = 1;
  required string xpath = 2;
  required ApiVariant orig_api_variant = 3; /**< which API variant was used to send RPC req. */
  repeated Value input = 4;
  repeated Node input_tree = 5;

  optional string subscriber_address = 10;
  optional uint32 subscription_id = 11;
}

/**
 * @brief Response to sr_rpc_send / sr_rpc_send_tree or sr_action_send / sr_action_send_tree request.
 */
message RPCResp {
  required bool action = 1;
  required string xpath = 2;
  required ApiVariant orig_api_variant = 3; /**< which API variant was used to send RPC req. */
  repeated Value output = 4;
  repeated Node output_tree = 5;
}


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

/**
 * @brief Sends an event notification into the datastore, will be delivered to all notification subscribers.
 * Sent by sr_event_notif_send API call.
 */
message EventNotifReq {
  /**
   * @brief Type of the event notification.
   */
  enum NotifType {
    REALTIME = 1;
    REPLAY = 2;
    REPLAY_COMPLETE = 3;
    REPLAY_STOP = 4;
  }

  /**
   * @brief Flags used to override default session handling.
   */
  enum NotifFlags {
    DEFAULT    = 0x00;     /**< Notification will be handled normally. */
    EPHEMERAL  = 0x01;     /**< Notification will not be stored in the notification store. */
  }

  required NotifType type = 1;
  required uint32 options = 2;  /**< Bitwise OR of NotifFlags. */

  required string xpath = 3;
  repeated Value values = 4;
  repeated Node trees = 5;
  required uint64 timestamp = 6;

  optional string subscriber_address = 10;
  optional uint32 subscription_id = 11;

  required bool do_not_send_reply = 20;
}

/**
 * @brief Response to sr_event_notif_send request.
 */
message EventNotifResp {
}

/**
 * @brief Sends a request to replay event notifications stored in the datastore.
 * Sent by sr_event_notif_replay API call.
 */
message EventNotifReplayReq {
  required string xpath = 1;
  required uint64 start_time = 2;
  required uint64 stop_time = 3;

  required string subscriber_address = 10;
  required uint32 subscription_id = 11;
  required ApiVariant api_variant = 12;
}

/**
 * @brief Response to sr_event_notif_replay request.
 */
message EventNotifReplayResp {
}


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

/**
 * @brief Requests operational data under given path form an operational data
 * provider.
 */
message DataProvideReq {
  required string xpath = 1;

  required string subscriber_address = 10;
  required uint32 subscription_id = 11;

  required uint64 request_id = 20;
}

/**
 * @brief Response to a request of operational data under given path form an
 * operational data provider.
 */
message DataProvideResp {
  required string xpath = 1;
  repeated Value values = 2;

  required uint64 request_id = 10;
}


////////////////////////////////////////////////////////////////////////////////
// Data modules handling API - internal, not exposed to the public API
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Requests installation / uinstallation of specified YANG model.
 * Sent by sr_module_install internal API calls.
 */
message ModuleInstallReq {
  required string module_name = 1;
  optional string revision = 2;
  optional string file_name = 3;
  required bool installed = 4;
}

/**
 * @brief Response to sr_module_install request.
 */
message ModuleInstallResp {
}

/**
 * @brief Requests enabling / disabling of specified YANG feature within the
 * YANG model. Sent by sr_feature_enable internal API calls.
 */
message FeatureEnableReq {
  required string module_name = 1;
  required string feature_name = 2;
  required bool enabled = 3;
}

/**
 * @brief Response to sr_feature_enable request.
 */
message FeatureEnableResp {
}


////////////////////////////////////////////////////////////////////////////////
// Sysrepo Engine internal messages
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Internal request to unsubscribe all subscriptions of a subscriber on given destination address.
 */
message UnsubscribeDestinationReq {
  required string destination = 1;
}

/**
 * @brief Internal request to timeout a commit, if it hasn't been terminated yet.
 */
message CommitTimeoutReq {
  required uint32 commit_id = 1;
  required bool expired = 2;
}

/**
 * @brief Internal request to timeout a request for operational data, if it hasn't been terminated yet.
 */
message OperDataTimeoutReq {
  required uint64 request_id = 1;
}

/**
 * @brief Internal request for internal state data (state data provided by Sysrepo Engine itself).
 */
message InternalStateDataReq {
  required uint64 request_id = 1;
  required string xpath = 2;
}

/**
 * @brief Internal request to cleanup aged notifications in the Notification Store.
 */
message NotifStoreCleanupReq {
}

/**
 * @brief Message to be delivered to the client after some timeout.
 */
message DelayedMsgReq {
  required Msg message = 1;
}

/**
 * @brief Internal request to reload NACM configuration from the running datastore.
 */
message NacmReloadReq {
}


////////////////////////////////////////////////////////////////////////////////
// Sysrepo Engine API umbrella messages
////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Requested operation.
 */
enum Operation {
  SESSION_START = 10;
  SESSION_STOP = 11;
  SESSION_REFRESH = 12;
  SESSION_CHECK = 13;
  SESSION_SWITCH_DS = 14;
  SESSION_SET_OPTS = 15;
  VERSION_VERIFY = 16;

  LIST_SCHEMAS = 20;
  GET_SCHEMA = 21;
  MODULE_INSTALL = 22;
  FEATURE_ENABLE = 23;

  GET_ITEM = 30;
  GET_ITEMS = 31;

  GET_SUBTREE = 32;
  GET_SUBTREES = 33;
  GET_SUBTREE_CHUNK = 34;

  SET_ITEM = 40;
  DELETE_ITEM = 41;
  MOVE_ITEM = 42;
  SET_ITEM_STR = 43;

  VALIDATE = 50;
  COMMIT = 51;
  DISCARD_CHANGES = 52;
  COPY_CONFIG = 53;

  LOCK = 60;
  UNLOCK = 61;

  SUBSCRIBE = 70;
  UNSUBSCRIBE = 71;
  CHECK_ENABLED_RUNNING = 72;
  GET_CHANGES = 73;

  DATA_PROVIDE = 80;
  CHECK_EXEC_PERMISSION = 81;
  RPC = 82;
  ACTION = 83;
  EVENT_NOTIF = 84;
  EVENT_NOTIF_REPLAY = 85;

  UNSUBSCRIBE_DESTINATION = 101;
  COMMIT_TIMEOUT = 102;
  OPER_DATA_TIMEOUT = 103;
  INTERNAL_STATE_DATA = 104;
  NOTIF_STORE_CLEANUP = 105;
  DELAYED_MSG = 106;
  NACM_RELOAD = 107;
}

/**
 * @brief Request for an operation.
 */
message Request {
  required uint64 _id = 1; /* Request ID used internally by sysrepo */
  required Operation operation = 2;

  optional SessionStartReq session_start_req = 10;
  optional SessionStopReq session_stop_req = 11;
  optional SessionRefreshReq session_refresh_req = 12;
  optional SessionCheckReq session_check_req = 13;
  optional SessionSwitchDsReq session_switch_ds_req = 14;
  optional SessionSetOptsReq session_set_opts_req = 15;
  optional VersionVerifyReq version_verify_req = 16;

  optional ListSchemasReq list_schemas_req = 20;
  optional GetSchemaReq get_schema_req = 21;
  optional ModuleInstallReq module_install_req = 22;
  optional FeatureEnableReq feature_enable_req = 23;

  optional GetItemReq get_item_req = 30;
  optional GetItemsReq get_items_req = 31;

  optional GetSubtreeReq get_subtree_req = 32;
  optional GetSubtreesReq get_subtrees_req = 33;
  optional GetSubtreeChunkReq get_subtree_chunk_req = 34;

  optional SetItemReq set_item_req = 40;
  optional DeleteItemReq delete_item_req = 41;
  optional MoveItemReq move_item_req = 42;
  optional SetItemStrReq set_item_str_req = 43;

  optional ValidateReq validate_req = 50;
  optional CommitReq commit_req = 51;
  optional DiscardChangesReq discard_changes_req = 52;
  optional CopyConfigReq copy_config_req = 53;

  optional LockReq lock_req = 60;
  optional UnlockReq unlock_req = 61;

  optional SubscribeReq subscribe_req = 70;
  optional UnsubscribeReq unsubscribe_req = 71;
  optional CheckEnabledRunningReq check_enabled_running_req = 72;
  optional GetChangesReq get_changes_req = 73;

  optional DataProvideReq data_provide_req = 80;
  optional CheckExecPermReq check_exec_perm_req = 81;
  optional RPCReq rpc_req = 82;
  optional EventNotifReq event_notif_req = 83;
  optional EventNotifReplayReq event_notif_replay_req = 84;
}

/**
 * @brief Response to the received request.
 */
message Response {
  required Operation operation = 1;
  required uint32 result = 2;  /**< Result of the operation. 0 on success, non-zero values map to sr_error_t enum in sysrepo.h. */
  optional Error error = 3;    /**< Additional error information. */

  optional SessionStartResp session_start_resp = 10;
  optional SessionStopResp session_stop_resp = 11;
  optional SessionRefreshResp session_refresh_resp = 12;
  optional SessionCheckResp session_check_resp = 13;
  optional SessionSwitchDsResp session_switch_ds_resp = 14;
  optional SessionSetOptsResp session_set_opts_resp = 15;
  optional VersionVerifyResp version_verify_resp = 16;

  optional ListSchemasResp list_schemas_resp = 20;
  optional GetSchemaResp get_schema_resp = 21;
  optional ModuleInstallResp module_install_resp = 22;
  optional FeatureEnableResp feature_enable_resp = 23;

  optional GetItemResp get_item_resp = 30;
  optional GetItemsResp get_items_resp = 31;

  optional GetSubtreeResp get_subtree_resp = 32;
  optional GetSubtreesResp get_subtrees_resp = 33;
  optional GetSubtreeChunkResp get_subtree_chunk_resp = 34;

  optional SetItemResp set_item_resp = 40;
  optional DeleteItemResp delete_item_resp = 41;
  optional MoveItemResp move_item_resp = 42;
  optional SetItemStrResp set_item_str_resp = 43;

  optional ValidateResp validate_resp = 50;
  optional CommitResp commit_resp = 51;
  optional DiscardChangesResp discard_changes_resp = 52;
  optional CopyConfigResp copy_config_resp = 53;

  optional LockResp lock_resp = 60;
  optional UnlockResp unlock_resp = 61;

  optional SubscribeResp subscribe_resp = 70;
  optional UnsubscribeResp unsubscribe_resp = 71;
  optional CheckEnabledRunningResp check_enabled_running_resp = 72;
  optional GetChangesResp get_changes_resp = 73;

  optional DataProvideResp data_provide_resp = 80;
  optional CheckExecPermResp check_exec_perm_resp = 81;
  optional RPCResp rpc_resp = 82;
  optional EventNotifResp event_notif_resp = 83;
  optional EventNotifReplayResp event_notif_replay_resp = 84;
}

/**
 * @brief Notification about an event that occurred in the datastore.
 */
message Notification {
  required SubscriptionType type = 1;
  required string destination_address = 2;
  required string source_address = 3;
  required uint32 source_pid = 4;
  required uint32 subscription_id = 5;
  optional uint32 commit_id = 6;

  optional ModuleInstallNotification module_install_notif = 10;
  optional FeatureEnableNotification feature_enable_notif = 11;
  optional ModuleChangeNotification module_change_notif = 12;
  optional SubtreeChangeNotification subtree_change_notif = 13;
}

/**
 * @brief Notification Acknowledgment.
 */
message NotificationAck {
  required Notification notif = 1;  /**< Original notification. */
  required uint32 result = 2;       /**< Result of the notification (success / error code). */
  optional Error error = 3;         /**< Additional error information. */
  required bool do_not_send_abort = 4; /**< If the result is error and this flag is set to true abort notification
                                       * will not be delivered to this subscriber
                                       * (Subscriber doesn't want notification about changes that he refused). */
}

/**
 * @brief Internal request sent by sysrepo. Should not be used from the public API.
 */
message InternalRequest {
  required Operation operation = 1;
  optional uint32 postpone_timeout = 2;

  optional UnsubscribeDestinationReq unsubscribe_dst_req = 10;
  optional CommitTimeoutReq commit_timeout_req = 11;
  optional OperDataTimeoutReq oper_data_timeout_req = 12;
  optional InternalStateDataReq internal_state_data_req = 13;
  optional NotifStoreCleanupReq notif_store_cleanup_req = 14;
  optional DelayedMsgReq delayed_msg_req = 15;
  optional NacmReloadReq nacm_reload_req = 16;
}

/**
 * @brief Umbrella sysrepo message used for communication between sysrepo
 * engine and client library.
 */
message Msg {
  /**
   * @brief Type of the message.
   */
  enum MsgType {
    REQUEST = 1;           /**< The message is a request. */
    RESPONSE = 2;          /**< The message is a response to the request. */
    NOTIFICATION = 3;      /**< The message is a notification. */
    NOTIFICATION_ACK = 4;  /**< The message is a notification acknowledgment. */
    INTERNAL_REQUEST = 5;  /**< The message is an internal request, should not be used from the public API. */
  }

  required MsgType type = 1;                      /**< Indicates type of the message. */
  required uint32 session_id = 2;                 /**< Session identifier. Can be 0 (value is ignored) for session_start and version_verify requests. */

  optional Request request = 3;                   /**< Filled in in case of type == REQUEST. */
  optional Response response = 4;                 /**< Filled in in case of type == RESPONSE. */
  optional Notification notification = 5;         /**< Filled in in case of type == NOTIFICATION. */
  optional NotificationAck notification_ack = 6;  /**< Filled in in case of type == NOTIFICATION_ACK */
  optional InternalRequest internal_request = 7;  /**< Filled in in case of type == INTERNAL. */

  required uint64 _sysrepo_mem_ctx = 20;          /**< Not part of the protocol. Used internally by Sysrepo to store a pointer to memory context. */
}
