/*
 * 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.onlab.graph;

import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;

/**
 * Pair of disjoint paths.
 *
 * @param <V> type of vertex
 * @param <E> type of edge
 */
public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {

    private Path<V, E> primary, secondary;
    boolean primaryActive = true;

    /**
     * Creates a disjoint path pair from two paths.
     *
     * @param primary   primary path
     * @param secondary secondary path
     */
    public DisjointPathPair(Path<V, E> primary, Path<V, E> secondary) {
        this.primary = primary;
        this.secondary = secondary;
    }

    @Override
    public V src() {
        return primary.src();
    }

    @Override
    public V dst() {
        return primary.dst();
    }

    /**
     * Returns the primary path.
     *
     * @return primary path
     */
    public Path<V, E> primary() {
        return primary;
    }

    /**
     * Returns the secondary path.
     *
     * @return primary path
     */
    public Path<V, E> secondary() {
        return secondary;
    }

    @Override
    public double cost() {
        return hasBackup() ? primary.cost() + secondary.cost() : primary.cost();
    }

    @Override
    public List<E> edges() {
        return primaryActive || !hasBackup() ? primary.edges() : secondary.edges();
    }

    /**
     * Checks if this path pair contains a backup/secondary path.
     *
     * @return boolean representing whether it has backup
     */
    public boolean hasBackup() {
        return secondary != null && secondary.edges() != null;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("src", src())
                .add("dst", dst())
                .add("cost", cost())
                .add("edges", edges())
                .toString();
    }

    @Override
    public int hashCode() {
        return hasBackup() ? Objects.hash(primary) + Objects.hash(secondary) :
                Objects.hash(primary);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DisjointPathPair) {
            final DisjointPathPair other = (DisjointPathPair) obj;
            return Objects.equals(this.src(), other.src()) &&
                    Objects.equals(this.dst(), other.dst()) &&
                    (Objects.equals(this.primary, other.primary) &&
                            Objects.equals(this.secondary, other.secondary)) ||
                    (Objects.equals(this.primary, other.secondary) &&
                            Objects.equals(this.secondary, other.primary));
        }
        return false;
    }

    /**
     * Returns number of paths inside this path pair object.
     *
     * @return number of paths
     */
    public int size() {
        return hasBackup() ? 2 : 1;
    }
}
