/*
 * Copyright (c) 1998, 2020 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     05/16/2008-1.0M8 Guy Pelletier
//       - 218084: Implement metadata merging functionality between mapping files
//     03/08/2010-2.1 Guy Pelletier
//       - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM
//     05/04/2010-2.1 Guy Pelletier
//       - 309373: Add parent class attribute to EclipseLink-ORM
//     05/14/2010-2.1 Guy Pelletier
//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
//     01/25/2011-2.3 Guy Pelletier
//       - 333488: Serializable attribute being defaulted to a variable one to one mapping and causing exception
//     07/16/2013-2.5.1 Guy Pelletier
//       - 412384: Applying Converter for parameterized basic-type for joda-time's DateTime does not work
package org.eclipse.persistence.internal.jpa.metadata.accessors.objects;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.libraries.asm.Opcodes;

/**
 * INTERNAL:
 * An object to hold onto a valid JPA decorated class.
 *
 * @author Guy Pelletier
 * @since TopLink 10.1.3/EJB 3.0 Preview
 */
public class MetadataClass extends MetadataAnnotatedElement {
    protected boolean m_isLazy;
    protected boolean m_isAccessible;
    protected boolean m_isPrimitive;
    protected boolean m_isJDK;
    protected int m_modifiers;

    // Stores the implements interfaces of this class.
    protected List<String> m_interfaces;

    // Stores a list of enclosed classes found inside this metadata class.
    // E.g. inner classes, enums etc.
    protected List<MetadataClass> m_enclosedClasses;

    // Store the classes field metadata, keyed by the field's name.
    protected Map<String, MetadataField> m_fields;

    // Store the classes method metadata, keyed by the method's name.
    // Method's next is used if multiple method with the same name.
    protected Map<String, MetadataMethod> m_methods;

    protected MetadataClass m_superclass;
    protected String m_superclassName;

    /**
     * Create the metadata class with the class name.
     */
    public MetadataClass(MetadataFactory factory, String name, boolean isLazy) {
        super(factory);
        setName(name);

        // By default, set the type to be the same as the name. The canonical
        // model generator relies on types which in most cases is the name, but
        // the generator resolves generic types a little differently to
        // correctly generate model classes.
        setType(name);

        m_isAccessible = true;
        m_isLazy = isLazy;
    }

    /**
     * Create the metadata class with the class name.
     */
    public MetadataClass(MetadataFactory factory, String name) {
        this(factory, name, false);
    }

    /**
     * Create the metadata class based on the class.
     * Mainly used for primitive defaults.
     */
    public MetadataClass(MetadataFactory factory, Class cls) {
        this(factory, cls.getName(), false);
        m_isPrimitive = cls.isPrimitive();
    }

    /**
     * INTERNAL:
     */
    public void addEnclosedClass(MetadataClass enclosedClass) {
        if (m_enclosedClasses == null) {
            m_enclosedClasses = new ArrayList<MetadataClass>();
        }

        m_enclosedClasses.add(enclosedClass);
    }

    /**
     * INTERNAL:
     */
    public void addField(MetadataField field) {
        if (m_fields == null) {
            m_fields = new HashMap<String, MetadataField>();
        }

        m_fields.put(field.getName(), field);
    }

    /**
     * INTERNAL:
     */
    public void addInterface(String interfaceName) {
        if (m_interfaces == null) {
            m_interfaces = new ArrayList<String>();
        }

        m_interfaces.add(interfaceName);
    }

    /**
     * INTERNAL:
     */
    public void addMethod(MetadataMethod method) {
        if (m_methods == null) {
            m_methods = new HashMap<String, MetadataMethod>();
        }

        m_methods.put(method.getName(), method);
    }

    /**
     * Allow comparison to Java classes and Metadata classes.
     */
    @Override
    public boolean equals(Object object) {
        if (object instanceof Class) {
            if (getName() == null) {
                // Void's name is null.
                return ((Class)object).getName() == null;
            }

            return getName().equals(((Class)object).getName());
        }

        return super.equals(object);
    }

    /**
     * INTERNAL:
     * Return if this class is or extends, or super class extends the class.
     */
    public boolean extendsClass(Class javaClass) {
        return extendsClass(javaClass.getName());
    }

    /**
     * INTERNAL:
     * Return if this class is or extends, or super class extends the class.
     */
    public boolean extendsClass(String className) {
        if (getName() == null) {
            return className == null;
        }

        if (getName().equals(className)) {
            return true;
        }

        if (getSuperclassName() == null) {
            return false;
        }

        if (getSuperclassName().equals(className)) {
            return true;
        }

        return getSuperclass().extendsClass(className);
    }

    /**
     * INTERNAL:
     * Return if this class is or extends, or super class extends the interface.
     */
    public boolean extendsInterface(Class javaClass) {
        return extendsInterface(javaClass.getName());
    }

    /**
     * INTERNAL:
     * Return if this class is or extends, or super class extends the interface.
     */
    public boolean extendsInterface(String className) {
        if (getName() == null) {
            return false;
        }

        if (getName().equals(className)) {
            return true;
        }

        if (getInterfaces().contains(className)) {
            return true;
        }

        for (String interfaceName : getInterfaces()) {
            if (getMetadataClass(interfaceName).extendsInterface(className)) {
                return true;
            }
        }

        if (getSuperclassName() == null) {
            return false;
        }

        return getSuperclass().extendsInterface(className);
    }

    /**
     * INTERNAL:
     * Return the list of classes defined within this metadata class. E.g.
     * enums and inner classes.
     */
    public List<MetadataClass> getEnclosedClasses() {
        if (m_enclosedClasses == null) {
            m_enclosedClasses = new ArrayList<MetadataClass>();
        }

        return m_enclosedClasses;
    }

    /**
     * INTERNAL:
     * Return the field with the name.
     * Search for any declared or inherited field.
     */
    public MetadataField getField(String name) {
        return getField(name, true);
    }

    /**
     * INTERNAL:
     * Return the field with the name.
     * Search for any declared or inherited field.
     */
    public MetadataField getField(String name, boolean checkSuperClass) {
        MetadataField field = getFields().get(name);

        if (checkSuperClass && (field == null) && (getSuperclassName() != null)) {
            return getSuperclass().getField(name);
        }

        return field;
    }

    /**
     * INTERNAL:
     */
    public Map<String, MetadataField> getFields() {
        if (m_fields == null) {
            m_fields = new HashMap<String, MetadataField>();

            if (m_isLazy) {
                m_factory.getMetadataClass(getName(), false);
            }
        }

        return m_fields;
    }

    /**
     * INTERNAL:
     */
    public List<String> getInterfaces() {
        if (m_interfaces == null) {
            m_interfaces = new ArrayList<String>();
        }

        return m_interfaces;
    }

    /**
     * INTERNAL:
     * Return the method with the name and no arguments.
     */
    protected MetadataMethod getMethod(String name) {
        return getMethods().get(name);
    }

    /**
     * INTERNAL:
     * Return the method with the name and argument types.
     */
    public MetadataMethod getMethod(String name, Class[] arguments) {
        List<String> argumentNames = new ArrayList<String>(arguments.length);

        for (int index = 0; index < arguments.length; index++) {
            argumentNames.add(arguments[index].getName());
        }

        return getMethod(name, argumentNames);
    }

    /**
     * INTERNAL:
     * Return the method with the name and argument types (class names).
     */
    public MetadataMethod getMethod(String name, List<String> arguments) {
        return getMethod(name, arguments, true);
    }

    /**
     * INTERNAL:
     * Return the method with the name and argument types (class names).
     */
    public MetadataMethod getMethod(String name, List<String> arguments, boolean checkSuperClass) {
        MetadataMethod method = getMethods().get(name);

        while ((method != null) && !method.getParameters().equals(arguments)) {
            method = method.getNext();
        }

        if (checkSuperClass && (method == null) && (getSuperclassName() != null)) {
            return getSuperclass().getMethod(name, arguments);
        }

        return method;
    }

    /**
     * INTERNAL:
     * Return the method with the name and argument types (class names).
     */
    public MetadataMethod getMethod(String name, String[] arguments) {
        return getMethod(name, Arrays.asList(arguments));
    }

    /**
     * INTERNAL:
     * Return the method for the given property name.
     */
    public MetadataMethod getMethodForPropertyName(String propertyName) {
        MetadataMethod method;

        String leadingChar = String.valueOf(propertyName.charAt(0)).toUpperCase();
        String restOfName = propertyName.substring(1);

        // Look for a getPropertyName() method
        method = getMethod(Helper.GET_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), new String[]{});

        if (method == null) {
            // Look for an isPropertyName() method
            method = getMethod(Helper.IS_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), new String[]{});
        }

        if (method != null) {
            method.setSetMethod(method.getSetMethod(this));
        }

        return method;
    }

    /**
     * INTERNAL:
     */
    public Map<String, MetadataMethod> getMethods() {
        if (m_methods == null) {
            m_methods = new HashMap<String, MetadataMethod>();

            if (m_isLazy) {
                m_factory.getMetadataClass(getName(), false);
            }
        }
        return m_methods;
    }

    /**
     * INTERNAL:
     */
    @Override
    public int getModifiers() {
        return m_modifiers;
    }

    /**
     * INTERNAL:
     */
    public MetadataClass getSuperclass() {
        if (m_superclass == null) {
            m_superclass = getMetadataClass(m_superclassName);
        }

        return m_superclass;
    }

    /**
     * INTERNAL:
     */
    public String getSuperclassName() {
        return m_superclassName;
    }

    /**
     * Return the ASM type name.
     */
    public String getTypeName() {
        if (isArray()) {
            return getName().replace('.', '/');
        } else if (isPrimitive()) {
            if (getName().equals("int")) {
                return "I";
            } else if (getName().equals("long")) {
                return "J";
            } else if (getName().equals("short")) {
                return "S";
            } else if (getName().equals("boolean")) {
                return "Z";
            } else if (getName().equals("float")) {
                return "F";
            } else if (getName().equals("double")) {
                return "D";
            } else if (getName().equals("char")) {
                return "C";
            } else if (getName().equals("byte")) {
                return "B";
            }
        }
        return "L" + getName().replace('.', '/') + ";";
    }

    /**
     * INTERNAL:
     * Return true is this class accessible to be found.
     */
    public boolean isAccessible() {
        return m_isAccessible;
    }

    /**
     * INTERNAL:
     * Return if this class is an array type.
     */
    public boolean isArray() {
        return (getName() != null) && (getName().charAt(0) == '[');
    }

    /**
     * INTERNAL:
     * Return if this is extends Collection.
     */
    public boolean isCollection() {
        return extendsInterface(Collection.class);
    }

    /**
     * INTERNAL:
     * Return if this is extends Enum.
     */
    public boolean isEnum() {
        return extendsClass(Enum.class);
    }

    /**
     * INTERNAL:
     * Return if this is an interface (super is null).
     */
    public boolean isInterface() {
        return (Opcodes.ACC_INTERFACE & m_modifiers) != 0;
    }

    /**
     * INTERNAL:
     * Return if this is a JDK (java/javax) class.
     */
    public boolean isJDK() {
        return m_isJDK;
    }

    /**
     * INTERNAL:
     */
    public boolean isLazy() {
        return m_isLazy;
    }

    /**
     * INTERNAL:
     * Return if this is extends List.
     */
    public boolean isList() {
        return extendsInterface(List.class);
    }

    /**
     * INTERNAL:
     * Return if this is extends Map.
     */
    public boolean isMap() {
        return extendsInterface(Map.class);
    }

    /**
     * INTERNAL:
     * Return if this is Object class.
     */
    public boolean isObject() {
        return getName().equals(Object.class.getName());
    }

    /**
     * INTERNAL:
     * Return if this is a primitive.
     */
    public boolean isPrimitive() {
        return m_isPrimitive;
    }

    /**
     * INTERNAL:
     * Return if this class extends Serializable or is an array type.
     */
    public boolean isSerializable() {
        if (isArray()) {
            return true;
        }

        return extendsInterface(Serializable.class);
    }

    /**
     * INTENAL:
     * Return true is this class is the Serializable.class interface.
     */
    public boolean isSerializableInterface() {
        return getName().equals(Serializable.class.getName());
    }

    /**
     * INTERNAL:
     * Return true if this extends Set.
     */
    public boolean isSet() {
        return extendsInterface(Set.class);
    }

    /**
     * INTERNAL:
     * Return if this is the void class.
     */
    public boolean isVoid() {
        return getName().equals(void.class.getName()) || getName().equals(Void.class.getName());
    }

    /**
     * INTERNAL:
     */
    public void setIsAccessible(boolean isAccessible) {
        m_isAccessible = isAccessible;
    }

    /**
     * INTERNAL:
     */
    public void setIsJDK(boolean isJDK) {
        m_isJDK = isJDK;
    }

    /**
     * INTERNAL:
     */
    public void setIsLazy(boolean isLazy) {
        m_isLazy = isLazy;
    }

    /**
     * INTERNAL:
     */
    @Override
    public void setModifiers(int modifiers) {
        m_modifiers = modifiers;
    }

    /**
     * INTERNAL:
     */
    @Override
    public void setName(String name) {
        super.setName(name);

        if ((!MetadataFactory.ALLOW_JDK) && (name.startsWith("java.")
                || name.startsWith("javax.") || name.startsWith("jakarta.")
                || name.startsWith("org.eclipse.persistence.internal."))) {
            setIsJDK(true);
        }
    }

    /**
     * INTERNAL:
     */
    public void setSuperclass(MetadataClass superclass) {
        m_superclass = superclass;
    }

    /**
     * INTERNAL:
     */
    public void setSuperclassName(String superclass) {
        m_superclassName = superclass;
    }
}