/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.
 */
package org.onosproject.net.group;

import org.onosproject.core.ApplicationId;
import org.onosproject.event.ListenerService;
import org.onosproject.net.DeviceId;

/**
 * Service for create/update/delete "group" in the devices.
 * Flow entries can point to a "group" defined in the devices that enables
 * to represent additional methods of forwarding like load-balancing or
 * failover among different group of ports or multicast to all ports
 * specified in a group.
 * "group" can also be used for grouping common actions of different flows,
 * so that in some scenarios only one group entry required to be modified
 * for all the referencing flow entries instead of modifying all of them.
 *
 * This implements semantics of a distributed authoritative group store
 * where the master copy of the groups lies with the controller and
 * the devices hold only the 'cached' copy.
 */
public interface GroupService
    extends ListenerService<GroupEvent, GroupListener> {

    /**
     * Creates a group in the specified device with the provided buckets.
     * This API provides an option for application to associate a cookie
     * while creating a group, so that applications can look-up the
     * groups based on the cookies. These Groups will be retained by
     * the core system and re-applied if any groups found missing in the
     * device when it reconnects. This API would immediately return after
     * submitting the request locally or to a remote Master controller
     * instance. As a response to this API invocation, GROUP_ADDED or
     * GROUP_ADD_FAILED notifications would be provided along with cookie
     * depending on the result of the operation on the device in the
     * data plane. The caller may also use "getGroup" API to get the
     * Group object created as part of this request.
     *
     * @param groupDesc group creation parameters
     *
     */
    void addGroup(GroupDescription groupDesc);

    /**
     * Returns a group object associated to an application cookie.
     *
     * NOTE1: The presence of group object in the system does not
     * guarantee that the "group" is actually created in device.
     * GROUP_ADDED notification would confirm the creation of
     * this group in data plane.
     *
     * @param deviceId device identifier
     * @param appCookie application cookie to be used for lookup
     * @return group associated with the application cookie or
     *               NULL if Group is not found for the provided cookie
     */
    Group getGroup(DeviceId deviceId, GroupKey appCookie);

    /**
     * Appends buckets to existing group. The caller can optionally
     * associate a new cookie during this updation. GROUP_UPDATED or
     * GROUP_UPDATE_FAILED notifications would be provided along with
     * cookie depending on the result of the operation on the device.
     *
     * @param deviceId device identifier
     * @param oldCookie cookie to be used to retrieve the existing group
     * @param buckets immutable list of group bucket to be added
     * @param newCookie immutable cookie to be used post update operation
     * @param appId Application Id
     */
    void addBucketsToGroup(DeviceId deviceId,
                           GroupKey oldCookie,
                           GroupBuckets buckets,
                           GroupKey newCookie,
                           ApplicationId appId);

    /**
     * Removes buckets from existing group. The caller can optionally
     * associate a new cookie during this updation. GROUP_UPDATED or
     * GROUP_UPDATE_FAILED notifications would be provided along with
     * cookie depending on the result of the operation on the device.
     *
     * @param deviceId device identifier
     * @param oldCookie cookie to be used to retrieve the existing group
     * @param buckets immutable list of group bucket to be removed
     * @param newCookie immutable cookie to be used post update operation
     * @param appId Application Id
     */
    void removeBucketsFromGroup(DeviceId deviceId,
                                GroupKey oldCookie,
                                GroupBuckets buckets,
                                GroupKey newCookie,
                                ApplicationId appId);

    /**
     * Deletes a group associated to an application cookie.
     * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
     * provided along with cookie depending on the result of the
     * operation on the device.
     *
     * @param deviceId device identifier
     * @param appCookie application cookie to be used for lookup
     * @param appId Application Id
     */
    void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId);

    /**
     * Retrieves all groups created by an application in the specified device
     * as seen by current controller instance.
     *
     * @param deviceId device identifier
     * @param appId application id
     * @return collection of immutable group objects created by the application
     */
    Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId);

    /**
     * Returns all groups associated with the given device.
     *
     * @param deviceId device ID to get groups for
     * @return iterable of device's groups
     */
    Iterable<Group> getGroups(DeviceId deviceId);

}
