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

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType;

/**
 * The abstract implementation of {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}
 * that is wrapping the runtime representation of a property.
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
public abstract class AbstractMethodMapping extends AbstractMapping {

    /**
     * Creates a new <code>AbstractMethodMapping</code>.
     *
     * @param parent The parent of this mapping
     * @param method The Java {@link Method} wrapped by this mapping
     */
    protected AbstractMethodMapping(IManagedType parent, Method method) {
        super(parent, method);
    }

    @Override
    public Method getMember() {
        return (Method) super.getMember();
    }

    @Override
    protected Annotation[] getMemberAnnotations() {
        return getMember().getAnnotations();
    }

    @Override
    protected Type getMemberGenericType() {
        return getMember().getGenericReturnType();
    }

    @Override
    protected Class<?> getMemberType() {

        Method method = getMember();
        Class<?> type = method.getReturnType();

        if (type == Void.class) {
            return method.getParameterTypes()[0];
        }
        else {

            // One to One
            OneToOne oneToOne = method.getAnnotation(OneToOne.class);
            if (oneToOne != null) {
                Class<?> targetEntity = oneToOne.targetEntity();
                if (targetEntity != void.class) {
                    return targetEntity;
                }
            }

            // Many to One
            ManyToOne manyToOne = method.getAnnotation(ManyToOne.class);
            if (manyToOne != null) {
                Class<?> targetEntity = manyToOne.targetEntity();
                if (targetEntity != void.class) {
                    return targetEntity;
                }
            }

            // Many to Many
            ManyToMany manyToMany = method.getAnnotation(ManyToMany.class);
            if (manyToMany != null) {
                Class<?> targetEntity = manyToMany.targetEntity();
                if (targetEntity != void.class) {
                    return targetEntity;
                }
            }

            // One to Many
            OneToMany oneToMany = method.getAnnotation(OneToMany.class);
            if (oneToMany != null) {
                Class<?> targetEntity = oneToMany.targetEntity();
                if (targetEntity != void.class) {
                    return targetEntity;
                }
            }

            return type;
        }
    }

    @Override
    public boolean hasAnnotation(Class<? extends Annotation> annotationType) {
        return getMember().isAnnotationPresent(annotationType);
    }
}
