/*
 * 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:
// dmccann - December 10/2009 - 2.0.1 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.internal.helper.ConversionManager;

/**
 * <p>
 * <b>Purpose:</b>The purpose of this class is to act as a dynamic proxy that
 * allows JDK Annotation method calls to be made on a non Annotation object.
 *
 * <p>
 * <b>Responsibilities:</b>
 * <ul>
 * <li>Create and return a dynamic proxy instance based on an Annotation class
 * and a <code>Map</code> of components (method name to value pairs)</li>
 * <li>Allow JDK Annotation method calls to be invoked on the proxy object</li>
 * </ul>
 * <p>
 * This class provides a means to invoke JDK Annotation method calls on a non
 * Annotation instance.
 *
 * @see java.lang.reflect.Proxy
 */
public class AnnotationProxy implements InvocationHandler {
    private Map<String, Object> components;
    private ConversionManager conversionMgr;
    private static final String ANNOTATION_TYPE_METHOD_NAME = "annotationType";

    /**
     * This constructor sets the <code>Map</code> of components (method name to
     * value pairs)and the ConversionManager to be used when converting values
     * in the <code>Map</code> based on the return type of the associated
     * <code>Method</code> Note that the preferred method of obtaining an
     * instance of this proxy class is via
     * <code>getProxy(Map, Class<A>, ClassLoader, ConversionManager)</code>
     *
     * @param components
     *            <code>Map</code> of method name to value pairs
     * @param conversionMgr
     *            <code>ConversionManager</code> instance for converting to the
     *            correct return type in the <code>invoke</code> method
     */
    private AnnotationProxy(Map<String, Object> components, ConversionManager conversionMgr) {
        this.components = components;
        this.conversionMgr = conversionMgr;
    }

    /**
     * This is the preferred way to obtain an instance of a dynamic proxy.
     *
     * The method takes a <code>ClassLoader</code> (which is used to load the
     * target <code>Annotation</code>), a <code>Class</code> (which indicates
     * the target <code>Annotation</code>, i.e.
     * <code>jakarta.xml.bind.annotation.XmlElement.class)</code>, and a
     * <code>Map</code> of method name to value pairs, which represent the
     * method names on the <code>Annotation</code> and the values that are to be
     * returned from each method call. For example, if this proxy is to be used
     * for an <code>@XmlElement</code>, the <code>Map</code> should contain the
     * following keys:
     *
     * <ul>
     * <li>defaultValue</li> <li>name</li> <li>namespace</li> <li>nillable</li>
     * <li>required</li> <li> type</li>
     * </ul>
     *
     * Following are example key/value pairs :
     *
     * <ul>
     * <li>"defaultValue", "##default"</li> <li>"name", "employee"</li> <li>
     * "namespace", "www.example.org"</li> <li>"nillable", false</li> <li>
     * "required", false</li> <li>"type",
     * jakarta.xml.bind.annotation.XmlElement.DEFAULT.class</li>
     * </ul>
     *
     * @param components
     *            <code>Map</code> of method name/value pairs for this proxy
     *            instance
     * @param annoClass
     *            The interface for the proxy class to implement
     * @param cl
     *            The <code>ClassLoader</code> to define the proxy class
     * @param conversionMgr
     *            <code>ConversionManager</code> instance for converting to the
     *            correct return type in the <code>invoke</code> method
     * @return A dynamic proxy instance based on a Java model JavaAnnotation
     */
    public static <A extends Annotation> A getProxy(Map<String, Object> components, Class<A> annoClass, ClassLoader cl, ConversionManager conversionMgr) {
        // add the 'annotationType' method name/value pair to the components map
        if (components == null) {
            components = new HashMap<String, Object>();
        }
        components.put(ANNOTATION_TYPE_METHOD_NAME, annoClass.getName());

        // Pass the classloader to the ConversionManager as well
        // conversionMgr.setLoader(cl);

        return (A) Proxy.newProxyInstance(cl, new Class[] { annoClass }, new AnnotationProxy(components, conversionMgr));
    }

    /**
     * Return the <code>Map</code> of method name/value pairs for this proxy
     * instance.
     *
     * @return <code>Map</code> of method name/value pairs for this proxy
     *         instance
     */
    public Map<String, Object> getComponents() {
        return this.components;
    }

    /**
     * Invoke a given <code>Method</code> on this proxy. The component
     * <code>Map</code> will be accessed using the given <code>Method</code>'s
     * name, and if an entry exists, the associated value is returned.
     *
     * @param proxy
     *            Satisfy the <code>InvocationHandler</code> interface - not
     *            used
     * @param method
     *            The <code>Method</code> instance corresponding to the
     *            interface method invoked on the proxy instance
     * @param args
     *            Satisfy the <code>InvocationHandler</code> interface - not
     *            used
     * @return The value from the method invocation on the proxy instance
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (components == null) {
            return null;
        }

        Class returnType = method.getReturnType();
        Object value = getComponents().get(method.getName());

        if (value == null && returnType == boolean.class) {
            return false;
        }
        if (value == null && returnType == Boolean.class) {
            return Boolean.FALSE;
        }

        if (returnType.isArray()) {
            return handleArrayData(returnType, value);
        }

        // use the ConversionManager to ensure that the correct type is returned
        return conversionMgr.convertObject(value, returnType);
    }

    private Object handleArrayData(Class returnType, Object value) {
        if (value == null) {
            return null;
        }

        Object[] data = (Object[]) value;
        Class componentType = returnType.getComponentType();
        Object[] convertedArray = (Object[]) Array.newInstance(componentType, data.length);

        for (int i = 0; i < data.length; i++) {
            convertedArray[i] = conversionMgr.convertObject(data[i], componentType);
        }

        return convertedArray;
    }

}
