/*
 * 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.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
    ) {
        super(appId, key, ImmutableSet.of(), selector, treatment, constraints,
              priority);

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

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


    /**
     * 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())
                .toString();
    }
}
