/*
 * Copyright 2014-present 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.Map;
import java.util.Set;

import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMap;
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.
 */
@Beta
public final class LinkCollectionIntent extends ConnectivityIntent {

    private final Set<Link> links;

    private final Set<ConnectPoint> ingressPoints;
    private final Set<ConnectPoint> egressPoints;
    private final boolean egressTreatmentFlag;
    /**
     * To manage multiple selectors use case.
     */
    private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
    /**
     * To manage multiple treatments use case.
     */
    private final Map<ConnectPoint, TrafficTreatment> egressTreatments;

    /**
     * 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
     * @param egressTreatment true if treatment should be applied by the egress device
     * @param ingressSelectors map to store the association ingress to selector
     * @param egressTreatments map to store the association egress to treatment
     * @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,
                                 boolean egressTreatment,
                                 Map<ConnectPoint, TrafficSelector> ingressSelectors,
                                 Map<ConnectPoint, TrafficTreatment> egressTreatments) {
        super(appId, key, resources(links), selector, treatment, constraints, priority);
        this.links = links;
        this.ingressPoints = ingressPoints;
        this.egressPoints = egressPoints;
        this.egressTreatmentFlag = egressTreatment;
        this.ingressSelectors = ingressSelectors;
        this.egressTreatments = egressTreatments;
    }

    /**
     * Constructor for serializer.
     */
    protected LinkCollectionIntent() {
        super();
        this.links = null;
        this.ingressPoints = null;
        this.egressPoints = null;
        this.egressTreatmentFlag = false;
        this.ingressSelectors = null;
        this.egressTreatments = 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;
        Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of();
        Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of();
        boolean egressTreatmentFlag;

        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 map ingress selectors to connection points of the intent.
         *
         * @param ingressSelectors maps connection point to traffic selector
         * @return this builder
         */
        public Builder ingressSelectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) {
            this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors);
            return this;
        }

        /**
         * Sets the map egress treatments to connection points of the intent.
         *
         * @param egressTreatments maps connection point to traffic treatment
         * @return this builder
         */
        public Builder egressTreatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) {
            this.egressTreatments = ImmutableMap.copyOf(egressTreatments);
            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;
        }

        /**
         * Sets the intent to apply treatment at the egress rather than the
         * ingress.
         *
         * @param treatmentOnEgress true applies treatment on egress device
         * @return this builder
         */
        public Builder applyTreatmentOnEgress(boolean treatmentOnEgress) {
            this.egressTreatmentFlag = treatmentOnEgress;
            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,
                    egressTreatmentFlag,
                    ingressSelectors,
                    egressTreatments
            );
        }
    }

    /**
     * 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;
    }

    /**
     * Returns the multiple selectors jointly with their connection points.
     * @return multiple selectors
     */
    public Map<ConnectPoint, TrafficSelector> ingressSelectors() {
        return ingressSelectors;
    }

    /**
     * Returns the multiple treatments jointly with their connection points.
     * @return multiple treatments
     */
    public Map<ConnectPoint, TrafficTreatment> egressTreatments() {
        return egressTreatments;
    }

    /**
     * Returns whether treatment should be applied on egress.
     *
     * @return the egress treatment flag
     */
    public boolean applyTreatmentOnEgress() {
        return egressTreatmentFlag;
    }

    @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())
                .add("selectors", ingressSelectors())
                .add("treatments", egressTreatments())
                .add("treatementOnEgress", applyTreatmentOnEgress())
                .toString();
    }
}
