/*
 * Copyright 2014-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.intent;

import java.util.List;
import java.util.Set;

import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;

/**
 * Abstraction of a connectivity intent that is implemented by a set of path
 * segments.
 */
public final class LinkCollectionIntent extends ConnectivityIntent {

    private final Set<Link> links;

    private final Set<ConnectPoint> ingressPoints;
    private final Set<ConnectPoint> egressPoints;

    /**
     * Creates a new actionable intent capable of funneling the selected
     * traffic along the specified convergent tree and out the given egress
     * point satisfying the specified constraints.
     *
     * @param appId       application identifier
     * @param key         key to use for the intent
     * @param selector    traffic match
     * @param treatment   action
     * @param links       traversed links
     * @param ingressPoints ingress points
     * @param egressPoints egress points
     * @param constraints optional list of constraints
     * @param priority    priority to use for the flows generated by this intent
     * @throws NullPointerException {@code path} is null
     */
    private LinkCollectionIntent(ApplicationId appId,
                                Key key,
                                TrafficSelector selector,
                                TrafficTreatment treatment,
                                Set<Link> links,
                                Set<ConnectPoint> ingressPoints,
                                Set<ConnectPoint> egressPoints,
                                List<Constraint> constraints,
                                int priority) {
        super(appId, key, resources(links), selector, treatment, constraints, priority);
        this.links = links;
        this.ingressPoints = ingressPoints;
        this.egressPoints = egressPoints;
    }

    /**
     * Constructor for serializer.
     */
    protected LinkCollectionIntent() {
        super();
        this.links = null;
        this.ingressPoints = null;
        this.egressPoints = null;
    }

    /**
     * Returns a new link collection intent builder. The application id,
     * ingress point and egress points are required fields.  If they are
     * not set by calls to the appropriate methods, an exception will
     * be thrown.
     *
     * @return single point to multi point builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder of a single point to multi point intent.
     */
    public static final class Builder extends ConnectivityIntent.Builder {
        Set<Link> links;
        Set<ConnectPoint> ingressPoints;
        Set<ConnectPoint> egressPoints;

        private Builder() {
            // Hide constructor
        }

        @Override
        public Builder appId(ApplicationId appId) {
            return (Builder) super.appId(appId);
        }

        @Override
        public Builder key(Key key) {
            return (Builder) super.key(key);
        }

        @Override
        public Builder selector(TrafficSelector selector) {
            return (Builder) super.selector(selector);
        }

        @Override
        public Builder treatment(TrafficTreatment treatment) {
            return (Builder) super.treatment(treatment);
        }

        @Override
        public Builder constraints(List<Constraint> constraints) {
            return (Builder) super.constraints(constraints);
        }

        @Override
        public Builder priority(int priority) {
            return (Builder) super.priority(priority);
        }

        /**
         * Sets the ingress point of the single point to multi point intent
         * that will be built.
         *
         * @param ingressPoints ingress connect points
         * @return this builder
         */
        public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
            return this;
        }

        /**
         * Sets the egress points of the single point to multi point intent
         * that will be built.
         *
         * @param egressPoints egress connect points
         * @return this builder
         */
        public Builder egressPoints(Set<ConnectPoint> egressPoints) {
            this.egressPoints = ImmutableSet.copyOf(egressPoints);
            return this;
        }

        /**
         * Sets the links of the link collection intent
         * that will be built.
         *
         * @param links links for the intent
         * @return this builder
         */
        public Builder links(Set<Link> links) {
            this.links = ImmutableSet.copyOf(links);
            return this;
        }


        /**
         * Builds a single point to multi point intent from the
         * accumulated parameters.
         *
         * @return point to point intent
         */
        public LinkCollectionIntent build() {

            return new LinkCollectionIntent(
                    appId,
                    key,
                    selector,
                    treatment,
                    links,
                    ingressPoints,
                    egressPoints,
                    constraints,
                    priority
            );
        }
    }


    /**
     * Returns the set of links that represent the network connections needed
     * by this intent.
     *
     * @return Set of links for the network hops needed by this intent
     */
    public Set<Link> links() {
        return links;
    }

    /**
     * Returns the ingress points of the intent.
     *
     * @return the ingress points
     */
    public Set<ConnectPoint> ingressPoints() {
        return ingressPoints;
    }

    /**
     * Returns the egress points of the intent.
     *
     * @return the egress points
     */
    public Set<ConnectPoint> egressPoints() {
        return egressPoints;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("id", id())
                .add("key", key())
                .add("appId", appId())
                .add("priority", priority())
                .add("resources", resources())
                .add("selector", selector())
                .add("treatment", treatment())
                .add("links", links())
                .add("ingress", ingressPoints())
                .add("egress", egressPoints())
                .toString();
    }
}
