/*******************************************************************************
 * 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.ofbiz.entity.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;

/**
 * Makes it easier to deal with entities that follow the
 * extensibility pattern and that can be of various types as identified in the database.
 */
public class EntityTypeUtil {

    public static final String module = EntityTypeUtil.class.getName();

    public static boolean isType(Collection<GenericValue> thisCollection, String typeRelation, GenericValue targetType) {
        for (GenericValue value: thisCollection) {
            try {
                GenericValue related = value.getRelatedOne(typeRelation, false);
                if (isType(related, targetType)) {
                    return true;
                } // else keep looking
            } catch (GenericEntityException e) {
                continue;
            }
        }
        return false;
    }

    /* public static boolean isType(Collection thisTypeCollection, GenericValue targetType) {
     Iterator iter = thisTypeCollection.iterator();
     while (iter.hasNext()) {
     if (isType((GenericValue) iter.next(), targetType)) {
     return true;
     }//else keep looking
     }
     return false;
     }*/

    /* private static Object getTypeID(GenericValue typeValue) {
     Collection keys = typeValue.getAllKeys();
     if (keys.size() == 1) {
     return keys.iterator().next();
     } else {
     throw new IllegalArgumentException("getTypeID expecting value with single key");
     }
     }*/

    private static GenericValue getParentType(GenericValue typeValue) {
        // assumes Parent relation is "Parent<entityName>"
        try {
            return typeValue.getRelatedOne("Parent" + typeValue.getEntityName(), true);
        } catch (GenericEntityException e) {
            Debug.logWarning(e, module);
            return null;
        }
    }

    public static List<GenericValue> getDescendantTypes(GenericValue typeValue) {
        // assumes Child relation is "Child<entityName>"
        List<GenericValue> descendantTypes = new ArrayList<GenericValue>();

        // first get all childrenTypes ...
        List<GenericValue> childrenTypes = null;
        try {
            childrenTypes = typeValue.getRelated("Child" + typeValue.getEntityName(), null, null, true);
        } catch (GenericEntityException e) {
            Debug.logWarning(e, module);
            return null;
        }
        if (childrenTypes == null)
            return null;

        // ... and add them as direct descendants
        descendantTypes.addAll(childrenTypes);

        // then add all descendants of the children
        for (GenericValue childType: childrenTypes) {
            List<GenericValue> childTypeDescendants = getDescendantTypes(childType);
            if (childTypeDescendants != null) {
                descendantTypes.addAll(childTypeDescendants);
            }
        }

        return descendantTypes;
    }

    public static boolean isType(GenericValue thisType, GenericValue targetType) {
        if (thisType == null) {
            return false;
        } else if (targetType.equals(thisType)) {
            return true;
        } else {
            return isType(getParentType(thisType), targetType);
        }
    }

    /**
     * A generic method to be used on Type enities, e.g. ProductType.  Recurse to the root level in the type hierarchy
     * and checks if the specified type childType has parentType as its parent somewhere in the hierarchy.
     *
     * @param delegator       The Delegator object.
     * @param entityName      Name of the Type entity on which check is performed.
     * @param primaryKey      Primary Key field of the Type entity.
     * @param childType       Type value for which the check is performed.
     * @param parentTypeField Field in Type entity which stores the parent type.
     * @param parentType      Value of the parent type against which check is performed.
     * @return boolean value based on the check results.
     */
    public static boolean hasParentType(Delegator delegator, String entityName, String primaryKey, String childType, String parentTypeField, String parentType) {
        GenericValue childTypeValue = null;
        try {
            childTypeValue = delegator.findOne(entityName, UtilMisc.toMap(primaryKey, childType), true);
        } catch (GenericEntityException e) {
            Debug.logError("Error finding "+entityName+" record for type "+childType, module);
        }
        if (childTypeValue != null) {
            if (parentType.equals(childTypeValue.getString(primaryKey))) return true;

            if (childTypeValue.getString(parentTypeField) != null) {
                if (parentType.equals(childTypeValue.getString(parentTypeField))) {
                    return true;
                } else {
                    return hasParentType(delegator, entityName, primaryKey, childTypeValue.getString(parentTypeField), parentTypeField, parentType);
                }
            }
        }

        return false;
    }
}
