/*
 * 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:
// mmacivor - April 25/2008 - 1.0M8 - Initial implementation
package org.eclipse.persistence.internal.jaxb;


import java.lang.reflect.Type;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.persistence.jaxb.TypeMappingInfo;
/**
 * INTERNAL:
 * <p><b>Purpose:</b>Provide a ClassLoader implementation to allow the definition of ASM generated
 * wrapper classes, and to lookup those classes when required.
 * <p><b>Responsibilities:</b><ul>
 * <li>Wrap the provided ClassLoader and pass method calls along</li>
 * <li>Maintain a map of generated wrapper classes and attempt lookups in that map if a class isn't found
 * in the nested loader</li>
 * <li>Provide a public API to define a class from an array of bytes and a class name</li></ul>
 * <p>This class is a ClassLoader implementation that maintains a map of wrapper classes generated during
 * JAXB generation. If a class is not found in the nested classLoader, then the map of generated classes
 * is checked.
 * @author mmacivor
 *
 */
public class JaxbClassLoader extends ClassLoader {

    private static final String GENERATED_CLASS_NAME = "org.eclipse.persistence.jaxb.generated";
    private Map<String, Type> generatedClasses;
    private AtomicInteger generatedClassCounter = new AtomicInteger();

    public JaxbClassLoader(ClassLoader nestedClassLoader) {
        super(nestedClassLoader);
        this.generatedClasses = new HashMap<String, Type>();
    }

    public JaxbClassLoader(ClassLoader nestedClassLoader, Class[] classes) {
        super(nestedClassLoader);
        this.generatedClasses = new HashMap();
        if(classes != null){
            for(int i=0; i<classes.length; i++){
                Class nextClass = classes[i];
                generatedClasses.put(nextClass.getName(), nextClass);
            }
        }
    }

    public JaxbClassLoader(ClassLoader nestedClassLoader, Type[] types) {
        super(nestedClassLoader);
        this.generatedClasses = new HashMap();
        if(types != null){
            for(int i=0; i<types.length; i++){
                Type nextType = types[i];
                if (nextType instanceof Class) {
                    generatedClasses.put(((Class)nextType).getName(), nextType);
                }
            }
        }

    }

    public JaxbClassLoader(ClassLoader nestedClassLoader, TypeMappingInfo[] types) {
        super(nestedClassLoader);
        this.generatedClasses = new HashMap();
        if(types != null){
            for(int i=0; i<types.length; i++){
                TypeMappingInfo tmi = types[i];
                Type nextType = tmi.getType();
                if(nextType == null){
                    throw org.eclipse.persistence.exceptions.JAXBException.nullTypeOnTypeMappingInfo(tmi.getXmlTagName());
                }
                if (nextType instanceof Class) {
                    generatedClasses.put(((Class)nextType).getName(), nextType);
                }
            }
        }
    }

    @Override
    public Class loadClass(String className) throws ClassNotFoundException {
        Class javaClass = null;
        if (className.indexOf('.') == -1 &&
            (className.equals("boolean") ||
            className.equals("short") ||
            className.equals("int") ||
            className.equals("long") ||
            className.equals("float") ||
            className.equals("double") ||
            className.equals("byte") ||
            className.equals("char"))) {
            javaClass = (Class)generatedClasses.get(className);
            if (javaClass != null) {
                return javaClass;
            }
        }
        try {
            javaClass = getParent().loadClass(className);
        } catch (ClassNotFoundException e) {
            javaClass = (Class)generatedClasses.get(className);
            if (javaClass != null) {
                return javaClass;
            }
            throw e;
        } catch (NoClassDefFoundError error) {
            javaClass = (Class)generatedClasses.get(className);
            if (javaClass == null) {
                throw error;
            }
        }
        return javaClass;
    }

    public Class generateClass(String className, byte[] bytes) {
        Class theClass = this.defineClass(className, bytes, 0, bytes.length);
        generatedClasses.put(className, theClass);
        return theClass;
    }

    public void putClass(String className, Class clazz) {
        generatedClasses.put(className, clazz);
    }

    public String nextAvailableGeneratedClassName() {
        return GENERATED_CLASS_NAME + generatedClassCounter.getAndIncrement();
    }

}
