/*
 * Copyright (c) 1998, 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 from Oracle TopLink
package org.eclipse.persistence.mappings.querykeys;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.expressions.DataExpression;
import org.eclipse.persistence.internal.expressions.ExpressionIterator;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.TableExpression;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;

/**
 * <p>
 * <b>Purpose</b>: Define an alias to a foreign object.
 * <p>
 * <b> Responsibilities</b>:
 * <ul>
 * <li> Define the reference class of the foreign object.
 * </ul>
 */
public class ForeignReferenceQueryKey extends QueryKey {
    protected Class referenceClass;
    protected String referenceClassName;
    protected Expression joinCriteria;

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this project to actual class-based
     * settings
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        Class referenceClass = null;
        try{
            if (referenceClassName != null){
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        referenceClass = AccessController.doPrivileged(new PrivilegedClassForName(referenceClassName, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(referenceClassName, exception.getException());
                    }
                } else {
                    referenceClass = PrivilegedAccessHelper.getClassForName(referenceClassName, true, classLoader);
                }
            }
            setReferenceClass(referenceClass);
        } catch (ClassNotFoundException exc){
            throw ValidationException.classNotFoundWhileConvertingClassNames(referenceClassName, exc);
        }
    }

    /**
     * PUBLIC:
     * Return the join expression for the relationship defined by the query key.
     */
    public Expression getJoinCriteria() {
        return joinCriteria;
    }

    /**
     * PUBLIC:
     * Return the reference class of the relationship.
     */
    public Class getReferenceClass() {
        return referenceClass;
    }

    /**
     * PUBLIC:
     * Return the reference class name of the relationship.
     */
    public String getReferenceClassName() {
        if (referenceClassName == null && referenceClass != null){
            referenceClassName = referenceClass.getName();
        }
        return referenceClassName;
    }

    /**
     * INTERNAL:
     * override the isForeignReferenceQueryKey() method in the superclass to return true.
     * @return boolean
     */
    @Override
    public boolean isForeignReferenceQueryKey() {
        return true;
    }

    /**
     * PUBLIC:
     * Set the join expression for the relationship defined by the query key.
     * <p>Example:
     * <blockquote><pre>
     *     builder.getField("ADDRESS.ADDRESS_ID").equal(builder.getParameter("EMPLOYEE.ADDR_ID");
     * </pre></blockquote>
     */
    public void setJoinCriteria(Expression joinCriteria) {
        this.joinCriteria = joinCriteria;
    }

    /**
     * PUBLIC:
     * Set the reference class of the relationship.
     * This is not required for direct collection query keys.
     */
    public void setReferenceClass(Class referenceClass) {
        this.referenceClass = referenceClass;
    }

    /**
     * PUBLIC:
     * Set the reference class name for this relationship
     * This is used when projects are built without using classes
     */
    public void setReferenceClassName(String referenceClassName) {
        this.referenceClassName = referenceClassName;
    }

    /**
     * PUBLIC:
     * Returns the source table.
     */
    public DatabaseTable getSourceTable() {
        // TODO: Should extract the target table from joinCriteria (if it's not null),
        // like ManyToManyQueryKey.getRelationTable does.
        return this.descriptor.getTables().firstElement();
    }

    /**
     * PUBLIC:
     * Returns the reference table.
     */
    public DatabaseTable getReferenceTable(ClassDescriptor desc) {
        // TODO: This won't work for direct collection.
        // Should extract the target table from joinCriteria (if it's not null),
        // like ManyToManyQueryKey.getRelationTable does.
        return desc.getTables().firstElement();
    }

    /**
     * PUBLIC:
     * Returns the relation table.
     * Currently only ManyToMany and OneToOne may have relation table.
     * The method is overridden to return null for other subclasses.
     * The returned relationTable still could be null.
     */
    public DatabaseTable getRelationTable(ClassDescriptor referenceDescriptor) {
        ExpressionIterator expIterator = new ExpressionIterator() {
            @Override
            public void iterate(Expression each) {
                if(each.isTableExpression()) {
                    ((Collection)this.getResult()).add(((TableExpression)each).getTable());
                }
                else if(each.isDataExpression()) {
                    DatabaseField field = ((DataExpression)each).getField();
                    if(field != null && field.hasTableName()) {
                        ((Collection)this.getResult()).add(field.getTable());
                    }
                } else if(each.isParameterExpression()) {
                    DatabaseField field = ((ParameterExpression)each).getField();
                    if(field != null && field.hasTableName()) {
                        ((Collection)this.getResult()).add(field.getTable());
                    }
                }
            }
        };

        expIterator.setResult(new HashSet());
        expIterator.iterateOn(this.joinCriteria);
        HashSet<DatabaseTable> tables = (HashSet)expIterator.getResult();

        DatabaseTable relationTable = null;
        Iterator<DatabaseTable> it = tables.iterator();
        while(it.hasNext()) {
            DatabaseTable table = it.next();
            // neither source nor reference descriptor contains table - must be relationTable
            if(!descriptor.getTables().contains(table) && !referenceDescriptor.getTables().contains(table)) {
                relationTable = table;
                break;
            }
        }
        return relationTable;
    }
}
