/*
 * Copyright 2014-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.Map;
import java.util.Set;

/**
 * Representation of a graph path search algorithm.
 *
 * @param <V> vertex type
 * @param <E> edge type
 */
public interface GraphPathSearch<V extends Vertex, E extends Edge<V>> {

    public static int ALL_PATHS = -1;

    /**
     * Abstraction of a path search result.
     */
    public interface Result<V extends Vertex, E extends Edge<V>> {

        /**
         * Returns the search source.
         *
         * @return search source
         */
        public V src();

        /**
         * Returns the search destination, if was was given.
         *
         * @return optional search destination
         */
        public V dst();

        /**
         * Returns the set of paths produced as a result of the graph search.
         *
         * @return set of paths
         */
        Set<Path<V, E>> paths();

        /**
         * Returns bindings of each vertex to its parent edges in the path.
         *
         * @return map of vertex to its parent edge bindings
         */
        public Map<V, Set<E>> parents();

        /**
         * Return a bindings of each vertex to its cost in the path.
         *
         * @return map of vertex to path cost bindings
         */
        public Map<V, Double> costs();
    }

    /**
     * Searches the specified graph for paths between vertices.
     *
     * @param graph    graph to be searched
     * @param src      optional source vertex
     * @param dst      optional destination vertex; if null paths to all vertex
     *                 destinations will be searched
     * @param weight   optional edge-weight; if null cost of each edge will be
     *                 assumed to be 1.0
     * @param maxPaths limit on number of paths; {@link GraphPathSearch#ALL_PATHS} if no limit
     * @return search results
     */
    Result<V, E> search(Graph<V, E> graph, V src, V dst,
                        EdgeWeight<V, E> weight, int maxPaths);

}
