/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.flowobjective;

import com.google.common.annotations.Beta;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;

import java.util.Collection;

/**
 * Represents a nexthop which will be translated by a driver
 * into the appropriate group or actions needed to implement
 * the egress function.
 *
 * A next objective is made up of a collection of traffic treatments
 * associated with a type. These types are:
 *
 * - Hashed
 * - Broadcast
 * - Failover
 * - Simple
 *
 * These types will indicate to the driver what the intended behavior is.
 * For example, a broadcast next objective with a collection of output
 * treatments will indicate to a driver that all output actions are expected
 * to be executed simultaneously. The driver is then free to implement this
 * as a group or a simple action list.
 */
@Beta
public interface NextObjective extends Objective {

    /**
     * Represents the type of next phase to build.
     */
    enum Type {
        /**
         * A hashed packet processing.
         */
        HASHED,

        /**
         * Broadcast packet process.
         */
        BROADCAST,

        /**
         * Failover handling.
         */
        FAILOVER,

        /**
         * Simple processing. Could be a group or a treatment.
         */
        SIMPLE
    }

    /**
     * The collection of treatments that need to be applied to a set of traffic.
     *
     * @return a collection of traffic treatments
     */
    Collection<TrafficTreatment> next();

    /**
     * The type of operation that will be applied to the traffic using the collection
     * of treatments.
     *
     * @return a type
     */
    Type type();

    /**
     * Auxiliary optional information provided to the device driver. Typically
     * conveys information about selectors (matches) that are intended to
     * use this Next Objective.
     *
     * @return a selector intended to pass meta information to the device driver.
     *         Value may be null if no meta information is provided.
     */
    TrafficSelector meta();

    /**
     * A next step builder.
     */
    interface Builder extends Objective.Builder {

        /**
         * Specifies the id for this next objective.
         *
         * @param nextId an integer
         * @return a next objective builder
         */
        Builder withId(int nextId);

        /**
         * Sets the type of next step.
         *
         * @param type a type
         * @return a next step builder
         */
        Builder withType(Type type);

        /**
         * Adds a treatment to this next step.
         *
         * @param treatment a traffic treatment
         * @return a next step builder
         */
        Builder addTreatment(TrafficTreatment treatment);

        /**
         * Specifies the application which applied the filter.
         *
         * @param appId an application id
         * @return an objective builder
         */
        @Override
        Builder fromApp(ApplicationId appId);

        /**
         * Sets the priority for this objective.
         *
         * @param priority an integer
         * @return an objective builder
         */
        @Override
        Builder withPriority(int priority);

        /**
         * Set meta information related to this next objective.
         *
         * @param selector match conditions
         * @return an objective builder
         */
        Builder withMeta(TrafficSelector selector);

        /**
         * Builds the next objective that will be added.
         *
         * @return a next objective
         */
        @Override
        NextObjective add();

        /**
         * Builds the next objective that will be removed.
         *
         * @return a next objective.
         */
        @Override
        NextObjective remove();

        /**
         * Builds the next objective that will be added.
         * The context will be used to notify the calling application.
         *
         * @param context an objective context
         * @return a next objective
         */
        @Override
        NextObjective add(ObjectiveContext context);

        /**
         * Builds the next objective that will be removed.
         * The context will be used to notify the calling application.
         *
         * @param context an objective context
         * @return a next objective
         */
        @Override
        NextObjective remove(ObjectiveContext context);

        /**
         * Build the next objective that will be added, with {@link Operation}
         * ADD_TO_EXISTING.
         *
         * @return a next objective
         */
        NextObjective addToExisting();

        /**
         * Build the next objective that will be removed, with {@link Operation}
         * REMOVE_FROM_EXISTING.
         *
         * @return a next objective
         */
        NextObjective removeFromExisting();

        /**
         * Builds the next objective that will be added, with {@link Operation}
         * ADD_TO_EXISTING. The context will be used to notify the calling application.
         *
         * @param context an objective context
         * @return a next objective
         */
        NextObjective addToExisting(ObjectiveContext context);

        /**
         * Builds the next objective that will be removed, with {@link Operation}
         * REMOVE_FROM_EXISTING. The context will be used to notify the calling application.
         *
         * @param context an objective context
         * @return a next objective
         */
        NextObjective removeFromExisting(ObjectiveContext context);

    }

}
