/*
 * 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
// Andrei Ilitchev May 28, 2008. Bug 224964: Provide support for Proxy Authentication through JPA.
//     Changed the was Proxy Authentication supported in case of thin driver, but support for oci case remains the same.
//     That caused re-arranging of the tests: before the fix all the tests were directly in proxiauthentication package;
//     now the old tests (minus thin-specific setup) were moved into the new proxyauthentication.oci package,
//     and the new tests defined in the new proxyauthentication.thin package.
package org.eclipse.persistence.testing.tests.proxyauthentication.oci;

import java.util.HashMap;
import java.util.Properties;

import java.sql.SQLException;

import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * Test Database change notification using JMS on top of Oracle AQ.
 */
public class ProxyAuthenticationOCITestModel extends TestModel {
    public ProxyAuthenticationOCITestModel() {
        super();
        this.proxyTestHelperClassName = "org.eclipse.persistence.testing.tests.proxyauthentication.oci.OCIProxyTestHelper";
    }
    protected Session oldSession;
    // Proxy Authentication user through which the session will be connected
    public static String connUser = "PA_CONN";
    public static String connPassword = "PA_CONN";
    // Proxy Authentication proxy user
    public static String proxyUser = "PA_PROXY";
    //    static protected String proxyPassword = "PA_PROXY";

    protected static HashMap proxyTestHelperMap = new HashMap();

    protected String proxyTestHelperClassName;
    protected ProxyTestHelper proxyTestHelper;

    @Override
    public void addTests() {
        Properties prop = proxyTestHelper.createProxyProperties(proxyUser);
        //        Properties prop = proxyTestHelper.createProxyProperties(proxyUser, proxyPassword);
        addTest(new NonPooledConnectionTestCase(prop, false));
        addTest(new NonPooledConnectionTestCase(prop, true));
        addTest(new PooledConnectionTestCase(prop));
        addTest(new ExternalConnectionPoolTestCase(prop, false));
        addTest(new ExternalConnectionPoolTestCase(prop, true));
        addTest(new MainLoginTestCase(prop));
    }

    @Override
    public void addRequiredSystems() {
        setupUser();

        /*        addRequiredSystem(
            new TestSystemAdapted(
                new EmployeeSystem(),
                new DbChangeNotificationAdapter(queueName, queueTableName, useMultipleConsumers)));*/
    }

    protected void setupUser() {
        if (!getSession().getPlatform().isOracle()) {
            throw new TestWarningException("Supports Oracle platform only");
        }

        oldSession = getSession();
        try {
            if (!((AbstractSession)getSession()).getAccessor().getConnection().getMetaData().getUserName().equalsIgnoreCase(connUser)) {
                /** to setup Proxy Authentication users in Oracle db, need to execute in sqlPlus or EnterpriseManager
                1 - Connect as sysdba
                connect sys/password as sysdba

                2 - Create connUser
                create user PA_CONN identified by PA_CONN
                grant connect to PA_CONN

                3 - Create proxyUser
                create user PA_PROXY identified by PA_PROXY
                grant connect to PA_PROXY

                4. Grant proxyUser connection through connUser
                alter user PA_PROXY grant connect through PA_CONN
            */
                DatabaseLogin login = (DatabaseLogin)oldSession.getLogin().clone();
                login.setUserName(connUser);
                login.setPassword(connPassword);
                DatabaseSession session = new Project(login).createServerSession();
                session.setSessionLog(getSession().getSessionLog());
                session.setLogLevel(getSession().getLogLevel());

                // get the specified proxyTestHelper, instantiate if not already exists.
                proxyTestHelper = (ProxyTestHelper)proxyTestHelperMap.get(proxyTestHelperClassName);
                if (proxyTestHelper == null) {
                    try {
                        proxyTestHelper = (ProxyTestHelper)Class.forName(proxyTestHelperClassName).getConstructor().newInstance();
                    } catch (Exception ex) {
                        throw new TestProblemException("Failed to instantiate proxyTestHelperClass " + proxyTestHelperClassName, ex);
                    }
                    proxyTestHelperMap.put(proxyTestHelperClassName, proxyTestHelper);
                }

                // normally user would set ProxyConnector into the login in preLogin event
                try {
                    proxyTestHelper.setProxyConnectorIntoLogin(login, oldSession);
                } catch (SQLException sqlException) {
                    throw new TestProblemException("Failed to create ProxyConnector ", sqlException);
                }

                try {
                    session.login();
                } catch (Exception exception) {
                    throw new TestProblemException("Database needs to be setup for ProxyAuthentication, needs PA_CONN, PA_PROXY users. See comments in ProxyAuthenticationInternalTestModel", exception);
                }

                getExecutor().setSession(session);
            }
        } catch (java.sql.SQLException se) {
            se.printStackTrace();
            throw new TestErrorException("There is SQLException");
        }
    }

    @Override
    public void reset() {
        if (oldSession != getExecutor().getSession()) {
            ((DatabaseSession)getSession()).logout();
            getExecutor().setSession(oldSession);
            try {
                proxyTestHelper.close();
            } catch (SQLException sqlException) {
                throw new TestErrorException("Failed to close ProxyConnector's adataSource ", sqlException);
            }
        }
    }
}
