/*
 * 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;
    }
}
