/*
 * Copyright 2016 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.newoptical;

import com.google.common.annotations.Beta;
import org.onlab.util.Bandwidth;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.OpticalCircuitIntent;
import org.onosproject.net.intent.OpticalConnectivityIntent;

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

/**
 * Entity to represent packet link realized by optical intent.
 */
@Beta
public class PacketLinkRealizedByOptical {
    private final ConnectPoint src, dst;
    private final Bandwidth bandwidth;
    // TODO should be list of Intent Key?
    private final Key realizingIntentKey;

    /**
     * Creates instance with specified parameters.
     *
     * @param src source connect point
     * @param dst destination connect point
     * @param realizingIntentKey key of Optical*Intent that realizes packet link between src and dst
     * @param bandwidth assigned bandwidth
     */
    public PacketLinkRealizedByOptical(ConnectPoint src, ConnectPoint dst,
                                       Key realizingIntentKey, Bandwidth bandwidth) {
        this.src = src;
        this.dst = dst;
        this.realizingIntentKey = realizingIntentKey;
        this.bandwidth = bandwidth;
    }

    /**
     * Creates PacketLinkRealizedByOptical instance with specified connect points and OpticalCircuitIntent.
     * Assigned bandwidth is taken from physical limit of optical link.
     *
     * @param src source connect point
     * @param dst destination connect point
     * @param intent OpticalCircuitIntent that realizes packet link between src and dst
     * @return PacketLinkRealizedByOptical instance with specified connect points and OpticalCircuitIntent
     */
    public static PacketLinkRealizedByOptical create(ConnectPoint src, ConnectPoint dst,
                                                     OpticalCircuitIntent intent) {
        checkNotNull(src);
        checkNotNull(dst);
        checkNotNull(intent);

        long rate = intent.getSignalType().bitRate();
        return new PacketLinkRealizedByOptical(src, dst, intent.key(), Bandwidth.bps(rate));
    }

    /**
     * Creates PacketLinkRealizedByOptical instance with specified connect points and OpticalConnectivityIntent.
     * Assigned bandwidth is taken from physical limit of optical link.
     *
     * @param src source connect point
     * @param dst destination connect point
     * @param intent OpticalConnectivityIntent that realizes packet link between src and dst
     * @return PacketLinkRealizedByOptical instance with specified connect points and OpticalConnectivityIntent
     */
    public static PacketLinkRealizedByOptical create(ConnectPoint src, ConnectPoint dst,
                                                     OpticalConnectivityIntent intent) {
        checkNotNull(src);
        checkNotNull(dst);
        checkNotNull(intent);

        long rate = intent.getSignalType().bitRate();
        return new PacketLinkRealizedByOptical(src, dst, intent.key(), Bandwidth.bps(rate));
    }

    /**
     * Returns source connect point.
     *
     * @return source connect point
     */
    public ConnectPoint src() {
        return src;
    }

    /**
     * Returns destination connect point.
     *
     * @return destination connect point
     */
    public ConnectPoint dst() {
        return dst;
    }

    /**
     * Returns assigned bandwidth.
     *
     * @return assigned bandwidth
     */
    public Bandwidth bandwidth() {
        return bandwidth;
    }

    /**
     * Returns intent key.
     *
     * @return intent key
     */
    public Key realizingIntentKey() {
        return realizingIntentKey;
    }

    /**
     * Check if packet link is between specified two connect points.
     *
     * @param src source connect point
     * @param dst destination connect point
     * @return true if this link is between src and dst.  false if not.
     */
    public boolean isBetween(ConnectPoint src, ConnectPoint dst) {
        return (this.src.equals(src) && this.dst.equals(dst));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        PacketLinkRealizedByOptical that = (PacketLinkRealizedByOptical) o;

        if (!src.equals(that.src)) {
            return false;
        }
        if (!dst.equals(that.dst)) {
            return false;
        }
        if (!bandwidth.equals(that.bandwidth)) {
            return false;
        }
        return realizingIntentKey.equals(that.realizingIntentKey);

    }

    @Override
    public int hashCode() {
        int result = src.hashCode();
        result = 31 * result + dst.hashCode();
        result = 31 * result + bandwidth.hashCode();
        result = 31 * result + realizingIntentKey.hashCode();
        return result;
    }
}
