/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 static com.google.common.base.MoreObjects.toStringHelper;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;

public class MutableAdjacencyListsGraph<V extends Vertex, E extends Edge<V>>
implements MutableGraph<V, E> {
    private Set<V> vertexes = new HashSet<V>();
    private Set<E> edges = new HashSet<E>();

    private SetMultimap<V, E> sources = HashMultimap.create();
    private SetMultimap<V, E> destinations = HashMultimap.create();

    /**
     * Creates a graph comprising of the specified vertexes and edges.
     *
     * @param vertex   set of graph vertexes
     * @param edge     set of graph edges
     */
    public MutableAdjacencyListsGraph(Set<V> vertex, Set<E> edge) {
        vertexes.addAll(vertex);
        edges.addAll(edge);
        for (E e : edge) {
            sources.put(e.src(), e);
            vertexes.add(e.src());
            destinations.put(e.dst(), e);
            vertexes.add(e.dst());
        }
    }

    @Override
    public Set<V> getVertexes() {
        return vertexes;
    }

    @Override
    public Set<E> getEdges() {
        return edges;
    }

    @Override
    public Set<E> getEdgesFrom(V src) {
        return sources.get(src);
    }

    @Override
    public Set<E> getEdgesTo(V dst) {
        return destinations.get(dst);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof MutableAdjacencyListsGraph) {
            MutableAdjacencyListsGraph that = (MutableAdjacencyListsGraph) obj;
            return this.getClass() == that.getClass() &&
                    Objects.equals(this.vertexes, that.vertexes) &&
                    Objects.equals(this.edges, that.edges);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(vertexes, edges);
    }

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


    @Override
    public void addVertex(V vertex) {
        if (vertexes != null) {
              if (!vertexes.contains(vertex)) {
                    vertexes.add(vertex);
                }
        }
    }

    @Override
    public void removeVertex(V vertex) {
        // TODO Auto-generated method stub
        if (vertexes != null && edges != null) {
            if (vertexes.contains(vertex)) {
                vertexes.remove(vertex);
                Set<E> srcEdgesList = sources.get(vertex);
                Set<E> dstEdgesList = destinations.get(vertex);
                edges.removeAll(srcEdgesList);
                edges.removeAll(dstEdgesList);
                sources.remove(vertex, srcEdgesList);
                sources.remove(vertex, dstEdgesList);
            }
        }
    }

    @Override
    public void addEdge(E edge) {
        if (edges != null) {
                if (!edges.contains(edge)) {
                    edges.add(edge);
                    sources.put(edge.src(), edge);
                    destinations.put(edge.dst(), edge);
                }
        }
    }

    @Override
    public void removeEdge(E edge) {
        if (edges != null) {
            if (edges.contains(edge)) {
                edges.remove(edge);
                sources.remove(edge.src(), edge);
                destinations.remove(edge.dst(), edge);
            }
        }
    }

    @Override
    public Graph<V, E> toImmutable() {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * Clear the graph.
     */
    public void clear() {
        edges.clear();
        vertexes.clear();
        sources.clear();
        destinations.clear();
    }
}
