module opendaylight-inventory {
    namespace "urn:opendaylight:inventory";
    prefix inv;

    import yang-ext { prefix ext; revision-date "2013-07-09"; }
    import ietf-inet-types { prefix inet; revision-date "2013-07-15"; }

    revision "2013-08-19" {
        description "Initial revision of Inventory model";
    }

    typedef support-type {
        type enumeration {
            enum native;
            enum emulated;
            enum not-supported;
        }
    }

    typedef node-id {
        type inet:uri;
        description "Identifier for a particular node. For example:

                         myprotocol:<unique_node_id>

                         myprotocol:12

                     It is a good practice to always lead with a scoping
                     identifier. In the example above the scoping was
                     'myprotocol'. In your app you could use 'myapp' etc.";
    }

    typedef node-connector-id {
        type inet:uri;
        description "Identifier for a particular node-connector. For example:

                         myprotocol:<unique_node_connector_id>
                         myprotocol:3

                     It is a good practice to always lead with a scoping
                     identifier. In the example above the scoping was
                     'myprotocol'. In your app you could use 'myapp' etc.";
    }

    // YANG does not have a statement which limits the scope of an
    // instance-identifier to a particular subtree, which is why we are using
    // a type capture and not an instance-identifier to define a node-ref and
    // a node-connector-ref.
    typedef node-ref {
        type instance-identifier;
        description "A reference that points to an
                     opendaylight-light:nodes/node in the data tree.";
    }

    typedef node-connector-ref {
        type instance-identifier;
        description "A reference that points to an
                     opendaylight-list:nodes/node/{node-id}/node-connector in
                     the data tree.";
    }

    identity node-context {
        description "A node-context is a classifier for node elements which
                     allows an RPC to provide a service on behalf of a
                     particular element in the data tree.";
    }

    identity node-connector-context {
        description "A node-connector-context is a classifier for
                     node-connector elements which allows an RPC to provide
                     a service on behalf of a particular element in the data
                     tree.";
    }

    // We are defining a base identity here because there are limitations with
    // YANG enums. YANG does not allow you to extend enumeratations, therefore
    // by defining a base identity we allow other yang files to extend this
    // identity to define additional "enumerations". By using node-type as
    // their base they are able to pass their object to fields that accept
    // "node-types" while uniquely describing their type of node, such as
    // "router-node" or "switch-node" etc.
    // See https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping#Identity
    // for more information.
    identity node-type {
        description "A base identity definition which represents a generic
                     node type and can be extended in other yang files.";
    }

    identity node-connector-type {
        description "A base identity definition which represents a generic
                     node connector type and can be extended in other YANG
                     files.";
    }

    grouping node {
        description "Describes the contents of a generic node -
                     essentially an ID and a list of node-connectors.
                     Acts as an augmentation point where other YANG files
                     can add additional information.";

        leaf id {
            type node-id;
            description "The unique identifier for the node.";
        }

        list "node-connector" {
            key "id";

            description "A list of node connectors that belong this node.";
            ext:context-instance "node-connector-context";

            uses node-connector;
        }
    }

    grouping node-connector {
        description "Describes a generic node connector which consists of an ID.
                     Acts as an augmentation point where other YANG files can
                     add additional information.";

        leaf id {
            type node-connector-id;
            description "The unique identifier for the node-connector.";
        }
    }

    grouping node-context-ref {
        description "A helper grouping which contains a reference to a node
                     classified with a node-context. This allows RPCs in other
                     YANG files to refine their input to a particular node
                     instance.";

        leaf node {
            ext:context-reference "node-context";
            type node-ref;
            description "A reference to a particular node.";
        }
    }

    // Base structure
    container nodes {
        description "The root container of all nodes.";

        list node {
            key "id";
            ext:context-instance "node-context";
            description "A list of nodes (as defined by the 'grouping node').";
            uses node; //this refers to the 'grouping node' defined above.
        }
    }

    // The following notifications should really be replaced by direct writes
    // to the data tree with data change listeners listening to those changes.
    // Notifications should be reserved for one time events which do not
    // require persistence to the data tree.
    notification node-updated {
        status deprecated;

        description "A notification sent by someone who realized there was
                     a modification to a node, but did not modify the data
                     tree.

                     Describes that something on the node has been updated
                     (including addition of a new node), but is for whatever
                     reason is not modifying the data tree.

                     Deprecated: If a process determines that a node was
                     updated, then that logic should update the node using
                     the DataBroker directly. Listeners interested update
                     changes should register a data change listener for
                     notifications on removals.";

        leaf node-ref {
            ext:context-reference "node-context";
            description "A reference to the node which changed.";

            type node-ref;
        }
        uses node;
    }

    notification node-connector-updated {
        status deprecated;

        description "A notification sent by someone who realized there was
                     a modification to a node-connector, but did not modify
                     the data tree.

                     Describes that something on the node-connector has been
                     updated (including addition of a new node-connector), but
                     is for whatever reason is not modifying the data tree.

                     Deprecated: If a process determines that a node-connector
                     was updated, then that logic should update the
                     node-connector using the DataBroker directly. Listeners
                     interested update changes should register a data change
                     listener for notifications on removals.";

        leaf node-connector-ref {
            ext:context-reference "node-connector-context";
            type node-connector-ref;
            description "A reference to the node-connector which changed.";
        }
        uses node-connector;
    }

    notification node-removed {
        status deprecated;

        description "A notification sent by someone who realized there was
                     a node was removed, but did not modify the data tree.

                     Describes that a node has been removed but is for whatever
                     reason is not modifying the data tree.

                     Deprecated: If a process determines that a node was
                     removed, then that logic should remove the node from
                     the DataBroker directly. Listeners interested in changes
                     should register a data change listener for notifications
                     on removals.";

        leaf node-ref {
            description "A reference to the node that was removed.";
            ext:context-reference "node-context";
            type node-ref;
        }
    }

    notification node-connector-removed {
        status deprecated;

        description "A notification sent by someone who realized there was
                     a node-connector was removed, but did not modify the data
                     tree.

                     Describes that a node-connector has been removed but is
                     for whatever reason is not modifying the data tree.

                     Deprecated: If a process determines that a node-connector
                     was removed, then that logic should remove the
                     node-connector from the DataBroker directly. Listeners
                     interested in changes should register a data change
                     listener for notifications on removals.";

        leaf node-connector-ref {
            description "A reference to the node-connector that was removed.";
            ext:context-reference "node-connector-context";
            type node-connector-ref;
        }
    }
}