/*
 * Copyright (c) 2006, 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:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.tests.jpql.tools.spi.java;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.tools.TypeHelper;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;
import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeRepository;

/**
 * The concrete implementation of {@link ITypeRepository} that is wrapping the Java class loader.
 *
 * @version 2.4
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class JavaTypeRepository implements ITypeRepository {

    /**
     * The repository used to access the application's classes.
     */
    private final ClassLoader classLoader;

    /**
     * The helper that gives access to the most common {@link IType types}.
     */
    private TypeHelper typeHelper;

    /**
     * The types that have been cached for faster access.
     */
    private final Map<String, JavaType> types;

    /**
     * The {@link IType} that represents a unresolvable or simply an unknown type, which is created
     * when {@link #getType(String)} is invoked with {@link IType#UNRESOLVABLE_TYPE}.
     */
    private JavaType unresolvableType;

    /**
     * Creates a new <code>JavaTypeRepository</code>.
     *
     * @param classLoader The repository used to access the application's classes
     */
    public JavaTypeRepository(ClassLoader classLoader) {
        super();
        this.classLoader = classLoader;
        this.types       = new HashMap<String, JavaType>();
    }

    /**
     * Retrieves the Java type for the given type name, which has to be the fully qualified type name.
     *
     * @param typeName The fully qualified type name
     * @return The Java type if it could be retrieved; <code>null</code> otherwise
     */
    protected Class<?> attemptLoadType(String typeName) {

        if (typeName.equals("boolean")) return Boolean  .TYPE;
        if (typeName.equals("byte"))    return Byte     .TYPE;
        if (typeName.equals("char"))    return Character.TYPE;
        if (typeName.equals("double"))  return Double   .TYPE;
        if (typeName.equals("float"))   return Float    .TYPE;
        if (typeName.equals("int"))     return Integer  .TYPE;
        if (typeName.equals("long"))    return Long     .TYPE;
        if (typeName.equals("short"))   return Short    .TYPE;

        try {
            return classLoader.loadClass(typeName);
        }
        catch (ClassNotFoundException e) {
            return null;
        }
    }

    protected JavaType buildType(Class<?> javaType) {
        JavaType type = new JavaType(this, javaType);
        types.put(javaType.getName(), type);
        return type;
    }

    protected JavaType buildType(String typeName) {
        return new JavaType(this, typeName);
    }

    /**
     * Returns the {@link ClassLoader} that is used to load Java classes.
     *
     * @return The {@link ClassLoader} that is used to load Java classes
     */
    public ClassLoader getClassLoader() {
        return classLoader;
    }

    @Override
    public IType getEnumType(String enumTypeName) {

        // Get the position of the last dot so we can remove the constant
        int lastDotIndex = enumTypeName.lastIndexOf(".");

        if (lastDotIndex == -1) {
            return null;
        }

        // Retrieve the fully qualified enum type name
        String typeName = enumTypeName.substring(0, lastDotIndex);

        // Attempt to load the enum type
        IType type = loadTypeImp(typeName);
        return type.isEnum() ? type : null;
    }

    @Override
    public JavaType getType(Class<?> javaClass) {
        return getType(javaClass.getName());
    }

    @Override
    public JavaType getType(String typeName) {

        if (typeName == IType.UNRESOLVABLE_TYPE) {
            return unresolvableType();
        }

        if (typeName.charAt(0) == '[') {
            return loadArrayType(typeName);
        }

        return loadTypeImp(typeName);
    }

    @Override
    public TypeHelper getTypeHelper() {
        if (typeHelper == null) {
            typeHelper = new TypeHelper(this);
        }
        return typeHelper;
    }

    protected JavaType loadArrayType(String typeName) {

        JavaType type = types.get(typeName);

        if (type == null) {
            try {
                type = new JavaType(this, Class.forName(typeName));
            }
            catch (ClassNotFoundException f) {
                type = new JavaType(this, typeName);
            }
            types.put(typeName, type);
        }

        return type;
    }

    protected JavaType loadInnerType(String typeName) {

        int index = typeName.lastIndexOf(".");

        if (index == -1) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        sb.append(typeName.substring(0, index));
        sb.append("$");
        sb.append(typeName.substring(index + 1, typeName.length()));
        typeName = sb.toString();

        return loadTypeImp(typeName);
    }

    protected JavaType loadTypeImp(String typeName) {

        JavaType type = types.get(typeName);

        // The type was already cached, simply return it
        if (type != null) {
            return type;
        }

        // Attempt to load the Java type
        Class<?> javaType = attemptLoadType(typeName);

        // A Java type exists, return it
        if (javaType != null) {
            return buildType(javaType);
        }

        // Now try with a possible inner type
        type = loadInnerType(typeName);

        if (type == null) {
            type = buildType(typeName);
        }

        return type;
    }

    protected JavaType unresolvableType() {
        if (unresolvableType == null) {
            unresolvableType = new JavaType(this, IType.UNRESOLVABLE_TYPE);
        }
        return unresolvableType;
    }
}
