/*
 * 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 com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.ResourceGroup;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.slf4j.Logger;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Abstraction of multiple source to single destination connectivity intent.
 */
@Beta
public final class MultiPointToSinglePointIntent extends ConnectivityIntent {

    private final Set<FilteredConnectPoint> ingressPoints;
    private final FilteredConnectPoint egressPoint;

    /**
     * Creates a new multi-to-single point connectivity intent for the specified
     * traffic selector and treatment with filtered connect point.
     *
     * @param appId         application identifier
     * @param key           intent key
     * @param selector      traffic selector
     * @param treatment     treatment
     * @param ingressPoints set of filtered ports from which ingress traffic originates
     * @param egressPoint   filtered port to which traffic will egress
     * @param constraints   constraints to apply to the intent
     * @param priority      priority to use for flows generated by this intent
     * @throws NullPointerException     if {@code ingressPoints} or
     *                                  {@code egressPoint} is null.
     * @throws IllegalArgumentException if the size of {@code ingressPoints} is
     *                                  not more than 1
     */
    private MultiPointToSinglePointIntent(ApplicationId appId,
                                          Key key,
                                          TrafficSelector selector,
                                          TrafficTreatment treatment,
                                          Set<FilteredConnectPoint> ingressPoints,
                                          FilteredConnectPoint egressPoint,
                                          List<Constraint> constraints,
                                          int priority,
                                          ResourceGroup resourceGroup) {
        super(appId, key, ImmutableSet.of(), selector, treatment, constraints,
              priority, resourceGroup);

        checkNotNull(ingressPoints);
        checkArgument(!ingressPoints.isEmpty(), "Ingress point set cannot be empty");
        checkNotNull(egressPoint);
        checkArgument(!ingressPoints.contains(egressPoint),
                      "Set of ingresses should not contain egress (egress: %s)", egressPoint);

        this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
        this.egressPoint = egressPoint;
    }

    /**
     * Constructor for serializer.
     */
    protected MultiPointToSinglePointIntent() {
        super();
        this.ingressPoints = null;
        this.egressPoint = null;
    }

    /**
     * Returns a new multi point to single point intent builder. The application id,
     * ingress points and egress point 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();
    }

    /**
     * Creates a new builder pre-populated with the information in the given
     * intent.
     *
     * @param intent initial intent
     * @return intent builder
     */
    public static Builder builder(MultiPointToSinglePointIntent intent) {
        return new Builder(intent);
    }

    /**
     * Builder of a multi point to single point intent.
     */
    public static final class Builder extends ConnectivityIntent.Builder {
        private final Logger log = getLogger(getClass());
        private Set<FilteredConnectPoint> ingressPoints;
        private FilteredConnectPoint egressPoint;

        private Builder() {
            // Hide constructor
        }

        /**
         * Creates a new builder pre-populated with information from the given
         * intent.
         *
         * @param intent initial intent
         */
        protected Builder(MultiPointToSinglePointIntent intent) {
            super(intent);

            this.filteredIngressPoints(intent.filteredIngressPoints())
                    .filteredEgressPoint(intent.filteredEgressPoint());

        }

        @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);
        }

        @Override
        public Builder resourceGroup(ResourceGroup resourceGroup) {
            return (Builder) super.resourceGroup(resourceGroup);
        }

        /**
         * Sets the ingress point of the single point to multi point intent
         * that will be built.
         *
         * @param ingressPoints ingress connect points
         * @return this builder
         */
        @Deprecated
        public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
            if (this.ingressPoints != null) {
                log.warn("Ingress points are already set, " +
                                 "this will override original ingress points.");
            }
            this.ingressPoints = ingressPoints.stream()
                    .map(FilteredConnectPoint::new)
                    .collect(Collectors.toSet());
            return this;
        }

        /**
         * Sets the egress point of the multi point to single point intent
         * that will be built.
         *
         * @param egressPoint egress connect point
         * @return this builder
         */
        @Deprecated
        public Builder egressPoint(ConnectPoint egressPoint) {
            if (this.egressPoint != null) {
                log.warn("Egress point is already set, " +
                                 "this will override original egress point.");
            }
            this.egressPoint = new FilteredConnectPoint(egressPoint);
            return this;
        }

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

        /**
         * Sets the filtered egress point of the multi point to single point intent
         * that will be built.
         *
         * @param egressPoint filtered egress connect point
         * @return this builder
         */
        public Builder filteredEgressPoint(FilteredConnectPoint egressPoint) {
            this.egressPoint = egressPoint;
            return this;
        }

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

            return new MultiPointToSinglePointIntent(
                    appId,
                    key,
                    selector,
                    treatment,
                    ingressPoints,
                    egressPoint,
                    constraints,
                    priority,
                    resourceGroup
            );
        }
    }


    /**
     * Returns the set of ports on which ingress traffic should be connected to
     * the egress port.
     *
     * @return set of ingress ports
     */
    public Set<ConnectPoint> ingressPoints() {
        return ingressPoints.stream()
                .map(FilteredConnectPoint::connectPoint)
                .collect(Collectors.toSet());
    }

    /**
     * Returns the port on which the traffic should egress.
     *
     * @return egress port
     */
    public ConnectPoint egressPoint() {
        return egressPoint.connectPoint();
    }

    /**
     * Returns the set of ports on which ingress traffic should be connected to
     * the egress port.
     *
     * @return set of ingress ports
     */
    public Set<FilteredConnectPoint> filteredIngressPoints() {
        return ingressPoints;
    }

    /**
     * Returns the port on which the traffic should egress.
     *
     * @return egress port
     */
    public FilteredConnectPoint filteredEgressPoint() {
        return egressPoint;
    }


    @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("ingress", ingressPoints())
                .add("egress", egressPoint())
                .add("filteredIngressCPs", filteredIngressPoints())
                .add("filteredEgressCP", filteredEgressPoint())
                .add("constraints", constraints())
                .add("resourceGroup", resourceGroup())
                .toString();
    }
}
