/*
 * 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.apache.myfaces.extensions.scripting.core.engine.dependencyScan.core;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * class dependency maps
 * note this class is thread save
 */
public class ClassDependencies {

    /**
     * reverse index which shows which
     * a class name and which classes in the system depend on that
     * classname
     * <p/>
     * <p/>
     * the key is a dependency a class has the _value is a set of classes which depend on the current class
     */
    private Map<String, Set<String>> reverseIndex = new ConcurrentHashMap<String, Set<String>>();

    public void addDependency(String referencingClass, String referencedClass) {
        Set<String> reverseDependencies = getReverseDependencies(referencedClass);
        reverseDependencies.add(referencingClass);
    }

    /**
     * adds a set of dependencies to the
     * reverse lookup index
     *
     * @param referencingClass  the referencing class of this dependency
     * @param referencedClasses the referenced class of this dependency
     */
    public void addDependencies(String referencingClass, Collection<String> referencedClasses) {
        for (String referencedClass : referencedClasses) {
            addDependency(referencingClass, referencedClass);
        }
    }

    /**
     * removes a referenced class an all its referencing classes!
     *
     * @param clazz the referenced class to be deleted
     */
    public void removeReferenced(String clazz) {
        reverseIndex.remove(clazz);
    }

    /**
     * removes a referencing class
     * and deletes the referenced
     * entry if it is not referenced anymore
     *
     * @param clazz the referencing class to delete
     */
    @SuppressWarnings("unused")
    public void removeReferrer(String clazz) {
        List<String> emptyReferences = new ArrayList<String>(reverseIndex.size());
        for (Map.Entry<String, Set<String>> entry : reverseIndex.entrySet()) {
            Set<String> entrySet = entry.getValue();
            entrySet.remove(clazz);
            if (entrySet.isEmpty()) {
                emptyReferences.add(entry.getKey());
            }
        }
        for (String toDelete : emptyReferences) {
            removeReferenced(toDelete);
        }
    }

    public Set<String> getReferringClasses(String referencedClass) {
        return reverseIndex.get(referencedClass);
    }

    private Set<String> getReverseDependencies(String dependency) {
        Set<String> dependencies = reverseIndex.get(dependency);
        if (dependencies == null) {
            dependencies = Collections.synchronizedSet(new HashSet<String>());
            reverseIndex.put(dependency, dependencies);
        }
        return dependencies;
    }

}
