/*
 * Copyright (c) 2012, 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:
//     02/08/2012-2.4 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     08/24/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     02/06/2013-2.5 Guy Pelletier
//       - 382503: Use of @ConstructorResult with createNativeQuery(sqlString, resultSetMapping) results in NullPointerException
package org.eclipse.persistence.queries;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * <p><b>Purpose</b>:
 * Concrete class to represent the ConstructorResult structure as defined by
 * the JPA 2.1 Persistence specification.
 *
 * @author Guy Pelletier
 * @since EclipseLink 2.4
 */
public class ConstructorResult extends SQLResult {
    /** Stores the class of result  */
    protected String targetClassName;
    protected transient Class targetClass;

    /** Stored the column results of this constructor result */
    protected List<ColumnResult> columnResults;

    protected transient Constructor constructor;
    protected Class[] constructorArgTypes;

    /**
     * Default constructor is protected. Users must initialize the constructor
     * result with a target class.
     */
    protected ConstructorResult() {
        columnResults = new ArrayList<>();
    }

    /**
     * Constructor accepting target class.
     */
    public ConstructorResult(Class targetClass){
        this();

        if (targetClass == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_constructor_result"));
        }

        this.targetClass = targetClass;
        this.targetClassName = targetClass.getName();
    }

    /**
     * Constructor accepting target class name.
     */
    public ConstructorResult(String targetClassName){
        this();

        if (targetClassName == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_value_for_constructor_result"));
        }

        this.targetClassName = targetClassName;
    }

    /**
     * Add a column result to this constructor result.
     */
    public void addColumnResult(ColumnResult columnResult) {
        columnResults.add(columnResult);
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this query to actual class-based
     * settings. This method is used when converting a project that has been built
     * with class names to a project with classes.
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);

        // Make sure the column results have been converted.
        for (ColumnResult columnResult : columnResults) {
            columnResult.convertClassNamesToClasses(classLoader);
        }

        //no need to get the class if we already have it
        if (targetClass == null && targetClassName!=null) {
            try{
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        targetClass = AccessController.doPrivileged(new PrivilegedClassForName(targetClassName, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(targetClassName, exception.getException());
                    }
                } else {
                    targetClass = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(targetClassName, true, classLoader);
                }
            } catch (ClassNotFoundException exc){
                throw ValidationException.classNotFoundWhileConvertingClassNames(targetClassName, exc);
            }
        }
    }

    /**
     * Return the columns result of this constructor result.
     */
    public List<ColumnResult> getColumnResults() {
        return columnResults;
    }

    /**
     * INTERNAL:
     * This method is a convenience method for extracting values from results/
     */
    @Override
    public Object getValueFromRecord(DatabaseRecord record, ResultSetMappingQuery query) {
        if (constructor == null) {
            initialize(record, query);
        }

        int columnResultsSize = getColumnResults().size();
        Object[] constructorArgs = new Object[columnResultsSize];

        for (int i = 0; i < columnResultsSize; i++) {
            constructorArgs[i] = ConversionManager.getDefaultManager().convertObject(record.get(getColumnResults().get(i).getColumn()), constructorArgTypes[i]);
        }

        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    return AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, constructorArgs));
                } catch (PrivilegedActionException exception) {
                    throw QueryException.exceptionWhileInitializingConstructor(exception.getException(), query, targetClass);
                }
            } else {
                return PrivilegedAccessHelper.invokeConstructor(constructor, constructorArgs);
            }
        } catch (IllegalAccessException exception) {
            throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass);
        } catch (java.lang.reflect.InvocationTargetException exception) {
            throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass);
        } catch (InstantiationException exception) {
            throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass);
        }
    }

    /**
     * INTERNAL:
     */
    protected void initialize(DatabaseRecord record, ResultSetMappingQuery query) {
        int columnResultsSize = getColumnResults().size();
        constructorArgTypes = new Class[columnResultsSize];

        for (int i = 0; i < columnResultsSize; i++) {
            ColumnResult result = getColumnResults().get(i);
            DatabaseField resultField = result.getColumn();

            if (resultField.getType() == null) {
                Object recordResultField = record.get(resultField);

                if (recordResultField == null) {
                    throw QueryException.columnResultNotFound(resultField);
                } else {
                    constructorArgTypes[i] = recordResultField.getClass();
                }
            } else {
                constructorArgTypes[i] = resultField.getType();
            }
        }

        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(targetClass, constructorArgTypes, true));
                } catch (PrivilegedActionException exception) {
                    throw QueryException.exceptionWhileInitializingConstructor(exception.getException(), query, targetClass);
                }
            } else {
                constructor = PrivilegedAccessHelper.getConstructorFor(targetClass, constructorArgTypes, true);
            }
        } catch (NoSuchMethodException exception) {
            throw QueryException.exceptionWhileInitializingConstructor(exception, query, targetClass);
        }
    }

    /**
     * Return true if this is a constructor result.
     */
    @Override
    public boolean isConstructorResult(){
        return true;
    }

    /**
     * Set columns result of this constructor result.
     */
    public void setColumnResults(List<ColumnResult> columnResults) {
        this.columnResults = columnResults;
    }
}
