package org.ovirt.engine.core.common.businessentities;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.ovirt.engine.core.compat.Guid;

/**
 * The {@code BusinessEntityMap} class stores a nameable business entities for efficient access by their ID or name.<br>
 * The {@code BusinessEntityMap} ignores {@code null} IDs or {@code null} names to be search by.
 */
public class BusinessEntityMap<E extends BusinessEntity<Guid> & Nameable> {
    private Map<String, E> entitiesByName;
    private Map<Guid, E> entitiesById;

    // added for the sake of checkstyle rule
    @SuppressWarnings("unused")
    private BusinessEntityMap() {
    }

    public BusinessEntityMap(Collection<E> entities) {
        entitiesByName = new HashMap<>();
        entitiesById = new HashMap<>();

        if (entities != null) {
            int nullValuedNames = 0;
            int nullValuedIds = 0;
            for (E e : entities) {
                if (e.getName() == null) {
                    nullValuedNames++;
                } else {
                    entitiesByName.put(e.getName(), e);
                }

                if (e.getId() == null) {
                    nullValuedIds++;
                } else {
                    entitiesById.put(e.getId(), e);
                }
            }

            if (entitiesByName.size() + nullValuedNames < entities.size() ||
                    entitiesById.size() + nullValuedIds < entities.size()) {
                throw new IllegalArgumentException("duplicates in input.");
            }
        }
    }

    public E get(String name) {
        return entitiesByName.get(name);
    }

    public E get(Guid id) {
        return entitiesById.get(id);
    }

    public boolean containsKey(String name) {
        return entitiesByName.containsKey(name);
    }

    public boolean containsKey(Guid id) {
        return entitiesById.containsKey(id);
    }

    /**
     * Returns an entity from the map by the given ID if not {@code null}, else by the given name.
     *
     * @param id
     *            the entity's ID
     * @param name
     *            the entity's name
     */
    public E get(Guid id, String name) {
        return id == null ? get(name) : get(id);
    }
}

@@ -931,30 +931,185 @@
     
-for (E e : entities) %7B
+int nonNullEntities = 0;%0A%0A            for (E e : entities) %7B%0A                if (e == null) %7B%0A                    continue;%0A                %7D%0A%0A                nonNullEntities++;
 %0A   
@@ -1537,31 +1537,27 @@
 s %3C 
-entities.size() %7C%7C%0A    
+nonNullEntities %7C%7C%0A
     
@@ -1610,23 +1610,23 @@
 s %3C 
-entities.size()
+nonNullEntities
 ) %7B%0A

allow null values to be passed into BusinessEntityMap