/*
 * 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:
//     05/28/2008-1.0M8 Andrei Ilitchev
//        - New file introduced for bug 224964: Provide support for Proxy Authentication through JPA.
package org.eclipse.persistence.platform.database.oracle;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import oracle.jdbc.OracleConnection;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.ConnectionCustomizer;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.Session;

/**
 * PUBLIC:
 * This class allows connection to open proxy session.
 */
public class OracleJDBC_10_1_0_2ProxyConnectionCustomizer extends ConnectionCustomizer {
    protected OracleConnection oracleConnection;
    protected int proxyType;
    protected Properties proxyProperties;

    /**
     * INTERNAL:
     * Should be instantiated only if session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE) != null.
     */
    public OracleJDBC_10_1_0_2ProxyConnectionCustomizer(Accessor accessor, Session session) {
        super(accessor, session);
    }

    /**
     * INTERNAL:
     * Applies customization to connection.
     * Called only if connection is not already customized (isActive()==false).
     * The method may throw SQLException wrapped into DatabaseException.
     * isActive method called after this method should return true only in case
     * the connection was actually customized.
     */
    @Override
    public void customize() {
        // Lazily initialize proxy properties - customize method may be never called
        // in case of ClientSession using external connection pooling.
        if(proxyProperties == null) {
            buildProxyProperties();
        }

        Connection connection = accessor.getConnection();
        if(connection instanceof OracleConnection) {
            oracleConnection = (OracleConnection)connection;
        } else {
            connection = session.getServerPlatform().unwrapConnection(connection);
            if(connection instanceof OracleConnection) {
                oracleConnection = (OracleConnection)connection;
            } else {
                throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnection();
            }
        }
        try {
            clearConnectionCache();
            Object[] args = null;
            if (this.session.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
                Properties logProperties = proxyProperties;
                if(proxyProperties.containsKey(OracleConnection.PROXY_USER_PASSWORD)) {
                    logProperties = (Properties)proxyProperties.clone();
                    logProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, "******");
                }
                args = new Object[]{ oracleConnection, logProperties };
            }
            if(oracleConnection.isProxySession()) {
                // Unexpectedly oracleConnection already has a proxy session - probably it was not closed when connection was returned back to connection pool.
                // That may happen on jta transaction rollback (especially triggered outside of user's thread - such as timeout)
                // when beforeCompletion is never issued
                // and application server neither closes proxySession nor allows access to connection in afterCompletion.
                try {
                    if (args != null) {
                        ((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_already_proxy_session", args);
                    }
                    oracleConnection.close(OracleConnection.PROXY_SESSION);
                } catch (SQLException exception) {
                    // Ignore
                    this.session.getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.CONNECTION, exception);
                }
            }
            oracleConnection.openProxySession(proxyType, proxyProperties);
            // 12c driver will default to an autoCommit setting of true on calling openProxySession
            oracleConnection.setAutoCommit(false);
            if (args != null) {
                ((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_opened_proxy_session", args);
            }
        } catch (SQLException exception) {
            oracleConnection = null;
            throw DatabaseException.sqlException(exception);
        } catch (NoSuchMethodError noSuchMethodError) {
            oracleConnection = null;
            throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnectionVersion();
        }
    }

    /**
     * INTERNAL:
     * Indicated whether the connection is currently customized.
     */
    @Override
    public boolean isActive() {
        return oracleConnection != null;
    }

    /**
     * INTERNAL:
     * Clears customization from connection.
     * Called only if connection is customized (isActive()==true).
     * If the method fails due to SQLException it should "eat" it
     * (just like DatasourceAccessor.closeConnection method).
     * isActive method called after this method should always return false.
     */
    @Override
    public void clear() {
        try {
            clearConnectionCache();
            if (this.session.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
                Properties logProperties = proxyProperties;
                if(proxyProperties.containsKey(OracleConnection.PROXY_USER_PASSWORD)) {
                    logProperties = (Properties)proxyProperties.clone();
                    logProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, "******");
                }
                Object[] args = new Object[]{ oracleConnection, logProperties };
                ((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_closing_proxy_session", args);
            }
            oracleConnection.close(OracleConnection.PROXY_SESSION);
        } catch (SQLException exception) {
            // Ignore
            this.session.getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.CONNECTION, exception);
        } finally {
            oracleConnection = null;
        }
    }

    /**
     * INTERNAL:
     * Normally called only when customizer is in inactive state (isActive()==false)
     * and followed by setAccessor call on the clone.
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError("clone not supported");
        }
    }

    /**
     * INTERNAL:
     * Two customizers considered equal if they produce the sane customization.
     */
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof OracleJDBC_10_1_0_2ProxyConnectionCustomizer) {
            return equals((OracleJDBC_10_1_0_2ProxyConnectionCustomizer)obj);
        } else {
            return false;
        }
    }

    /**
     * INTERNAL:
     * Two customizers considered equal if they produce the sane customization.
     */
    public boolean equals(OracleJDBC_10_1_0_2ProxyConnectionCustomizer customizer) {
        if(this == customizer) {
            return true;
        }
        if(this.proxyProperties == null) {
            buildProxyProperties();
        }
        if(customizer.proxyProperties == null) {
            customizer.buildProxyProperties();
        }
        return this.proxyType == customizer.proxyType && this.proxyProperties.equals(customizer.proxyProperties);
    }

    /**
     * INTERNAL:
     * Precondition: session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE) != null
     */
    protected void buildProxyProperties() {
        Object proxyTypeValue = session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE);
        try {
            proxyType = ((Integer)session.getPlatform().getConversionManager().convertObject(proxyTypeValue, Integer.class)).intValue();
        } catch (ConversionException conversionException) {
            throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresIntProxytype();
        }
        proxyProperties = new Properties();
        if(proxyType == OracleConnection.PROXYTYPE_USER_NAME) {
            String proxyUserName = (String)session.getProperty(OracleConnection.PROXY_USER_NAME);
            if(proxyUserName != null) {
                proxyProperties.setProperty(OracleConnection.PROXY_USER_NAME, proxyUserName);
            } else {
                ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_USER_NAME", OracleConnection.PROXY_USER_NAME);
            }
        } else if(proxyType == OracleConnection.PROXYTYPE_DISTINGUISHED_NAME) {
            String distinguishedName = (String)session.getProperty(OracleConnection.PROXY_DISTINGUISHED_NAME);
            if(distinguishedName != null) {
                proxyProperties.setProperty(OracleConnection.PROXY_DISTINGUISHED_NAME, distinguishedName);
            } else {
                ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_DISTINGUISHED_NAME", OracleConnection.PROXY_DISTINGUISHED_NAME);
            }
        } else if(proxyType == OracleConnection.PROXYTYPE_CERTIFICATE) {
            Object certificate = session.getProperty(OracleConnection.PROXY_CERTIFICATE);
            if(certificate != null) {
                proxyProperties.put(OracleConnection.PROXY_CERTIFICATE, certificate);
            } else {
                ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_CERTIFICATE", OracleConnection.PROXY_CERTIFICATE);
            }
        } else {
            ValidationException.unknownProxyType(proxyType, "OracleConnection.PROXYTYPE_USER_NAME", "OracleConnection.PROXYTYPE_DISTINGUISHED_NAME", "OracleConnection.PROXYTYPE_CERTIFICATE");
        }
        String proxyUserPassword = (String)session.getProperty(OracleConnection.PROXY_USER_PASSWORD);
        // set the value if it's not null and not an empty String
        if(proxyUserPassword != null && proxyUserPassword.length() > 0) {
            proxyProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, proxyUserPassword);
        }
        Object proxyRoles = session.getProperty(OracleConnection.PROXY_ROLES);
        // set the value if it's not null and not an empty String
        if(proxyRoles != null && !((proxyRoles instanceof String) && (((String)proxyRoles).length() == 0))) {
            proxyProperties.put(OracleConnection.PROXY_ROLES, proxyRoles);
        }
    }

    /**
     * INTERNAL:
     * Clears connection's both implicit and explicit caches.
     */
    protected void clearConnectionCache() {
        this.getSession().getServerPlatform().clearStatementCache(this.getAccessor().getConnection());
        ((DatabaseAccessor)this.getAccessor()).clearStatementCache((AbstractSession)this.getSession());
    }
}
