/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 com.google.common.annotations.Beta;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.ResourceGroup;
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.checkNotNull;

/**
 * Abstraction of bidirectional connectivity between two points in the network.
 */
@Beta
public final class TwoWayP2PIntent extends ConnectivityIntent {

    private final ConnectPoint one;
    private final ConnectPoint two;


    /**
     * Creates a new host-to-host intent with the supplied host pair.
     *
     * @param appId       application identifier
     * @param key         intent key
     * @param one         first host
     * @param two         second host
     * @param selector    action
     * @param treatment   ingress port
     * @param constraints optional prioritized list of path selection constraints
     * @param priority    priority to use for flows generated by this intent
     * @param resourceGroup resource group for this intent
     * @throws NullPointerException if {@code one} or {@code two} is null.
     */
    private TwoWayP2PIntent(ApplicationId appId, Key key,
                            ConnectPoint one, ConnectPoint two,
                            TrafficSelector selector,
                            TrafficTreatment treatment,
                            List<Constraint> constraints,
                            int priority,
                            ResourceGroup resourceGroup) {
        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
              priority, resourceGroup);

        // TODO: consider whether the case one and two are same is allowed
        this.one = checkNotNull(one);
        this.two = checkNotNull(two);

    }

    /**
     * Returns a new two way intent builder.
     *
     * @return two way intent builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder of a point to point intent.
     */
    public static final class Builder extends ConnectivityIntent.Builder {
        ConnectPoint one;
        ConnectPoint two;

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

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

        /**
         * Sets the first connection point of the two way intent that will be built.
         *
         * @param one first connect point
         * @return this builder
         */
        public Builder one(ConnectPoint one) {
            this.one = one;
            return this;
        }

        /**
         * Sets the second connection point of the two way intent that will be built.
         *
         * @param two second connect point
         * @return this builder
         */
        public Builder two(ConnectPoint two) {
            this.two = two;
            return this;
        }

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

            return new TwoWayP2PIntent(
                    appId,
                    key,
                    one,
                    two,
                    selector,
                    treatment,
                    constraints,
                    priority,
                    resourceGroup
            );
        }
    }

    /**
     * Returns identifier of the first host.
     *
     * @return first host identifier
     */
    public ConnectPoint one() {
        return one;
    }

    /**
     * Returns identifier of the second host.
     *
     * @return second host identifier
     */
    public ConnectPoint two() {
        return two;
    }

    @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("constraints", constraints())
                .add("resourceGroup", resourceGroup())
                .add("one", one)
                .add("two", two)
                .toString();
    }

}
