/*
 * Copyright (c) 2011, 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:
//     Rick Barkhouse - 2.1 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.xjc;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaModel;

import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;

/**
 * INTERNAL:
 * <p>
 * <b>Purpose:</b> <code>JavaModel</code> implementation wrapping XJC's <code>JCodeModel</code>.  Used when
 * bootstrapping a <code>DynamicJAXBContext</code> from an XML Schema.
 * </p>
 *
 * <p>
 * <b>Responsibilities:</b>
 * </p>
 * <ul>
 *    <li>Return a <code>JavaClass</code> based on a <code>Class</code> or <code>Class</code> name.</li>
 *    <li>Return a Java <code>Annotation</code> for a given <code>JavaAnnotation</code>.</li>
 * </ul>
 *
 * @since EclipseLink 2.1
 *
 * @see org.eclipse.persistence.jaxb.javamodel.JavaModel
 */
public class XJCJavaModelImpl implements JavaModel {

    private JCodeModel jCodeModel;
    private DynamicClassLoader dynamicClassLoader;
    private Map<String, JavaClass> javaModelClasses = new HashMap<>();

    /**
     * Construct a new instance of <code>XJCJavaModelImpl</code>.
     *
     * @param codeModel - the XJC <code>JCodeModel</code> to be wrapped.
     * @param loader - the <code>ClassLoader</code> used to bootstrap the <code>DynamicJAXBContext</code>.
     */
    public XJCJavaModelImpl(JCodeModel codeModel, DynamicClassLoader loader) {
        this.jCodeModel = codeModel;
        this.dynamicClassLoader = loader;
    }

    /**
     * Obtain the <code>JavaClass</code> given the corresponding Java <code>Class</code>.
     *
     * @param jClass - the Java <code>Class</code> to search for.
     *
     * @return the <code>JavaClass</code> corresponding to <code>jClass</code>.
     */
    @Override
    public JavaClass getClass(Class<?> jClass) {
        if (jClass == null) {
            return null;
        }

        JavaClass cachedClass = this.javaModelClasses.get(jClass.getCanonicalName());
        if (cachedClass != null) {
            return cachedClass;
        }

        try {
            XJCJavaClassImpl jc = new XJCJavaClassImpl(jCodeModel._class(jClass.getCanonicalName()), jCodeModel, dynamicClassLoader);
            jc.setJavaModel(this);
            this.javaModelClasses.put(jClass.getCanonicalName(), jc);
            return jc;
        } catch (JClassAlreadyExistsException ex) {
            XJCJavaClassImpl jc = new XJCJavaClassImpl(jCodeModel._getClass(jClass.getCanonicalName()), jCodeModel, dynamicClassLoader);
            this.javaModelClasses.put(jClass.getCanonicalName(), jc);
            jc.setJavaModel(this);
            return jc;
        }
    }

    /**
     * Obtain the <code>JavaClass</code> given the corresponding Java <code>Class'</code> name.
     *
     * @param className - the name of the Java <code>Class</code> to search for.
     *
     * @return the <code>JavaClass</code> corresponding to <code>className</code>.
     */
    @Override
    public JavaClass getClass(String className) {
        JavaClass cachedClass = this.javaModelClasses.get(className);
        if (cachedClass != null) {
            return cachedClass;
        }

        String componentName = className;
        boolean isArray = className.contains("[]");
        if (isArray) {
            componentName = className.replace("[]", "");
        }

        boolean isTyped = className.contains("<");
        if (isTyped) {
            // Only keep the generic part
            componentName = componentName.substring(0, className.indexOf('<'));
        }

        boolean isPrimitive = XMLConversionManager.getPrimitiveClass(componentName) != null;
        try {
            JavaClass jc = new XJCJavaClassImpl(jCodeModel._class(componentName), jCodeModel, dynamicClassLoader, isArray, isPrimitive);
            this.javaModelClasses.put(className, jc);
            return jc;
        } catch (JClassAlreadyExistsException ex) {
            JavaClass jc = new XJCJavaClassImpl(jCodeModel._getClass(componentName), jCodeModel, dynamicClassLoader, isArray, isPrimitive);
            this.javaModelClasses.put(className, jc);
            return jc;
        }
    }

    /**
     * Return a Java <code>Annotation</code> representation of the given <code>JavaAnnotation</code>.
     *
     * @param annotation - the <code>JavaAnnotation</code> to be converted.
     * @param jClass - the Java <code>Class</code> this annotation belogs to.
     *
     * @return a Java <code>Annotation</code> representation of the given <code>JavaAnnotation</code>.
     */
    @Override
    public Annotation getAnnotation(JavaAnnotation annotation, Class<?> jClass) {
        return ((XJCJavaAnnotationImpl) annotation).getJavaAnnotation();
    }

    /**
     * Returns a <code>Map</code> of this <code>JavaModel's</code> <code>JavaClasses</code>, keyed on class name.
     *
     * @return this <code>JavaModel's</code> <code>Map</code> of <code>JavaClasses</code>.
     */
    public Map<String, JavaClass> getJavaModelClasses() {
        return javaModelClasses;
    }

    /**
     * Sets the <code>Map</code> of <code>JavaClasses</code> for this <code>JavaModel's</code>, keyed on class name.
     *
     * @param javaModelClasses - a <code>Map</code> of <code>JavaClasses</code>, keyed on class name.
     */
    public void setJavaModelClasses(Map<String, JavaClass> javaModelClasses) {
        this.javaModelClasses = javaModelClasses;
    }

    /**
     * Returns this <code>JavaModel's</code> <code>ClassLoader</code>.
     *
     * @return the <code>ClassLoader</code> used by this <code>JavaModel</code>.
     */
    @Override
    public ClassLoader getClassLoader() {
        return this.dynamicClassLoader;
    }

}
