/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.core.descriptors;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.internal.core.descriptors.CoreInstantiationPolicy;
import org.eclipse.persistence.internal.core.descriptors.CoreObjectBuilder;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;

/**
 * INTERNAL
 * A abstraction of descriptor capturing behavior common to all persistence
 * types.
 */
public abstract class CoreDescriptor<
    ATTRIBUTE_GROUP extends CoreAttributeGroup,
    DESCRIPTOR_EVENT_MANAGER extends CoreDescriptorEventManager,
    FIELD extends CoreField,
    INHERITANCE_POLICY extends CoreInheritancePolicy,
    INSTANTIATION_POLICY extends CoreInstantiationPolicy,
    LIST extends List,
    OBJECT_BUILDER extends CoreObjectBuilder> implements Serializable {

    protected DESCRIPTOR_EVENT_MANAGER eventManager;
    protected FIELD field;
    protected INSTANTIATION_POLICY instantiationPolicy;
    protected INHERITANCE_POLICY inheritancePolicy;
    protected OBJECT_BUILDER objectBuilder;

    protected Map<String, ATTRIBUTE_GROUP> attributeGroups;

    /**
     * Default constructor.
     */
    protected CoreDescriptor() {
    }

    /**
     * Adds the attribute group to this descriptor.
     */
    public void addAttributeGroup(ATTRIBUTE_GROUP group) {
        if (this.attributeGroups == null){
            this.attributeGroups = new HashMap<>();
        }
        this.attributeGroups.put(group.getName(), group);
    }


    /**
     * PUBLIC:
     * Returns the attribute group corresponding to the name provided.
     * If no group is found with the specified name, null is returned.
     */
    public ATTRIBUTE_GROUP getAttributeGroup(String name){
        if (this.attributeGroups == null){
            return null;
        }else if (name != null){
            return this.attributeGroups.get(name);
        }else{
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_argument_get_attributegroup"));
        }
    }

    /**
     * ADVANCED:
     * Returns the attribute groups for this Descriptor.
     */
    public Map<String, ATTRIBUTE_GROUP> getAttributeGroups(){
        return this.attributeGroups;
    }

    /**
     * PUBLIC:
     * Get the event manager for the descriptor.  The event manager is responsible
     * for managing the pre/post selectors.
     */
    public abstract DESCRIPTOR_EVENT_MANAGER getEventManager();

    /**
     * PUBLIC:
     * The inheritance policy is used to define how a descriptor takes part in inheritance.
     * All inheritance properties for both child and parent classes is configured in inheritance policy.
     * Caution must be used in using this method as it lazy initializes an inheritance policy.
     * Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.
     */
    public abstract INHERITANCE_POLICY getInheritancePolicy();

    /**
     * INTERNAL:
     * Returns the instantiation policy.
     */
    public abstract INSTANTIATION_POLICY getInstantiationPolicy();

    /**
     * PUBLIC:
     * Return the java class.
     */
    public abstract <T> Class<T> getJavaClass();

    /**
     * INTERNAL:
     * Return the object builder
     */
    public abstract OBJECT_BUILDER getObjectBuilder();

    /**
     * PUBLIC:
     * Return the names of all the primary keys.
     */
    public abstract List<String> getPrimaryKeyFieldNames();

    /**
     * INTERNAL:
     * Return all the primary key fields
     */
    public abstract List<FIELD> getPrimaryKeyFields();

    /**
     * INTERNAL:
     * searches first descriptor than its ReturningPolicy for an equal field
     */
    public abstract FIELD getTypedField(FIELD field);

    /**
     * INTERNAL:
     * returns true if a DescriptorEventManager has been set.
     */
    public abstract boolean hasEventManager();

    /**
     * INTERNAL:
     * Return if this descriptor is involved in inheritance, (is child or parent).
     * Note: If this class is part of table per class inheritance strategy this
     * method will return false.
     * @see org.eclipse.persistence.descriptors.ClassDescriptor#hasTablePerClassPolicy
     */
    public abstract boolean hasInheritance();

    /**
     * INTERNAL:
     * Set the event manager for the descriptor.  The event manager is responsible
     * for managing the pre/post selectors.
     */
    public abstract void setEventManager(DESCRIPTOR_EVENT_MANAGER eventManager);

    /**
     * INTERNAL:
     * Sets the inheritance policy.
     */
    public abstract void setInheritancePolicy(INHERITANCE_POLICY inheritancePolicy);

    /**
     * INTERNAL:
     * Sets the instantiation policy.
     */
    public abstract void setInstantiationPolicy(INSTANTIATION_POLICY instantiationPolicy);

    /**
    * PUBLIC:
    * Set the Java class that this descriptor maps.
    * Every descriptor maps one and only one class.
    */
    public abstract void setJavaClass(Class<?> javaClass);

    /**
     * INTERNAL:
     * Set the ObjectBuilder.
     */
    protected abstract void setObjectBuilder(OBJECT_BUILDER objectBuilder);

    /**
     * PUBLIC:
     * User can specify a vector of all the primary key field names if primary key is composite.
     *
     * @see org.eclipse.persistence.descriptors.ClassDescriptor#addPrimaryKeyFieldName(String)
     */
    public abstract void setPrimaryKeyFieldNames(LIST primaryKeyFieldNames);

    /**
     * PUBLIC:
     * User can specify a vector of all the primary key field names if primary key is composite.
     *
     * @see org.eclipse.persistence.descriptors.ClassDescriptor#addPrimaryKeyFieldName(String)
     */
    public abstract void setPrimaryKeyFields(List<FIELD> primaryKeyFields);
}
