/*
 * Copyright 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.Collections;
import java.util.List;
import java.util.Optional;

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

import com.google.common.base.MoreObjects;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;


/**
 * Abstraction of MPLS label-switched connectivity.
 */
@Beta
public final class MplsIntent extends ConnectivityIntent {

    private final ConnectPoint ingressPoint;
    private final Optional<MplsLabel> ingressLabel;
    private final ConnectPoint egressPoint;
    private final Optional<MplsLabel> egressLabel;

    /**
     * Creates a new point-to-point intent with the supplied ingress/egress
     * ports, labels and constraints.
     *
     * @param appId        application identifier
     * @param selector     traffic selector
     * @param treatment    treatment
     * @param ingressPoint ingress port
     * @param ingressLabel ingress MPLS label
     * @param egressPoint  egress port
     * @param egressLabel  egress MPLS label
     * @param constraints  optional list of constraints
     * @param priority    priority to use for flows generated by this intent
     * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
     */
    private MplsIntent(ApplicationId appId,
                      Key key,
                      TrafficSelector selector,
                      TrafficTreatment treatment,
                      ConnectPoint ingressPoint,
                      Optional<MplsLabel> ingressLabel,
                      ConnectPoint egressPoint,
                      Optional<MplsLabel> egressLabel,
                      List<Constraint> constraints,
                      int priority) {

        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
              priority);

        this.ingressPoint = checkNotNull(ingressPoint);
        this.ingressLabel = checkNotNull(ingressLabel);
        this.egressPoint = checkNotNull(egressPoint);
        this.egressLabel = checkNotNull(egressLabel);

        checkArgument(!ingressPoint.equals(egressPoint),
                "ingress and egress should be different (ingress: %s, egress: %s)",
                ingressPoint, egressPoint);
    }

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

    /**
     * Builder of an MPLS intent.
     */
    public static final class Builder extends ConnectivityIntent.Builder {
        ConnectPoint ingressPoint;
        ConnectPoint egressPoint;
        Optional<MplsLabel> ingressLabel;
        Optional<MplsLabel> egressLabel;

        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 point to point intent that will be built.
         *
         * @param ingressPoint ingress connect point
         * @return this builder
         */
        public Builder ingressPoint(ConnectPoint ingressPoint) {
            this.ingressPoint = ingressPoint;
            return this;
        }

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

        /**
         * Sets the ingress label of the intent that will be built.
         *
         * @param ingressLabel ingress label
         * @return this builder
         */
        public Builder ingressLabel(Optional<MplsLabel> ingressLabel) {
            this.ingressLabel = ingressLabel;
            return this;
        }

        /**
         * Sets the ingress label of the intent that will be built.
         *
         * @param egressLabel ingress label
         * @return this builder
         */
        public Builder egressLabel(Optional<MplsLabel> egressLabel) {
            this.egressLabel = egressLabel;
            return this;
        }

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

            return new MplsIntent(
                    appId,
                    key,
                    selector,
                    treatment,
                    ingressPoint,
                    ingressLabel,
                    egressPoint,
                    egressLabel,
                    constraints,
                    priority
            );
        }
    }



    /**
     * Constructor for serializer.
     */
    protected MplsIntent() {
        super();
        this.ingressPoint = null;
        this.ingressLabel = null;
        this.egressPoint = null;
        this.egressLabel = null;
    }

    /**
     * Returns the port on which the ingress traffic should be connected to
     * the egress.
     *
     * @return ingress switch port
     */
    public ConnectPoint ingressPoint() {
        return ingressPoint;
    }

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


    /**
     * Returns the MPLS label which the ingress traffic should tagged.
     *
     * @return ingress MPLS label
     */
    public Optional<MplsLabel> ingressLabel() {
        return ingressLabel;
    }

    /**
     * Returns the MPLS label which the egress traffic should tagged.
     *
     * @return egress MPLS label
     */
    public Optional<MplsLabel> egressLabel() {
        return egressLabel;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("id", id())
                .add("appId", appId())
                .add("key", key())
                .add("priority", priority())
                .add("selector", selector())
                .add("treatment", treatment())
                .add("ingressPoint", ingressPoint)
                .add("ingressLabel", ingressLabel)
                .add("egressPoint", egressPoint)
                .add("egressLabel", egressLabel)
                .add("constraints", constraints())
                .toString();
    }



}
