/*
 * 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.internal.sessions.factories.model.login;

import java.util.Vector;
import org.eclipse.persistence.internal.security.SecurableObjectHolder;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.SequencingConfig;

/**
 * INTERNAL:
 */
public abstract class LoginConfig {
    private String m_platformClass;
    private String m_username;
    private char[] m_encryptedPassword;
    private SecurableObjectHolder m_securableObjectHolder;
    private String m_tableQualifier;
    private boolean m_externalConnectionPooling;
    private boolean m_externalTransactionController;
    private SequencingConfig m_sequencingConfig;
    private Vector m_propertyConfigs;

    protected LoginConfig() {
        // Without setting the encryption class name the object holder will
        // default to JCE.
        m_securableObjectHolder = new SecurableObjectHolder();
    }

    public void setPlatformClass(String platformClass) {
        m_platformClass = platformClass;
    }

    public String getPlatformClass() {
        return m_platformClass;
    }

    public void setUsername(String username) {
        m_username = username;
    }

    public String getUsername() {
        return m_username;
    }

    public void setEncryptionClass(String encryptionClass) {
        m_securableObjectHolder.setEncryptionClassName(encryptionClass);
    }

    public String getEncryptionClass() {
        return m_securableObjectHolder.getEncryptionClassName();
    }

    /**
     * This method will always encrypt the password regardless. Should only
     * ever be called from the Mapping Workbench.
     * It can be called before setting an encryption class, therefore, the
     * securable object initialization remains in the constructor with default
     * to JCE and changes only if an encryption class is set.
     *
     * @param password
     */
    public void setPassword(String password) {
        setEncryptedPassword(password);
    }

    /**
     * This method should never be called from the Mapping Workbench. Instead it
     * is called only at load time of a schema formatted sessions.xml file. It
     * assumes the password is encrypted. If it is not we will make sure it is
     * encrypted.
     *
     * @param encryptedPassword
     */
    public void setEncryptedPassword(String encryptedPassword) {
        // Bug 4117441 - Secure programming practices, store password in char[]
        if (encryptedPassword == null) {
            // respect explicit de-referencing of password
            m_encryptedPassword = null;
        } else if (encryptedPassword.length() == 0) {
            m_encryptedPassword = new char[0];
        } else {
            // If the decrypted password is the same as the encrypted one then
            // it was not encrypted so make sure to store the encrypted password.
            if (encryptedPassword.equals(m_securableObjectHolder.getSecurableObject().decryptPassword(encryptedPassword))) {
                m_encryptedPassword = m_securableObjectHolder.getSecurableObject().encryptPassword(encryptedPassword).toCharArray();
            } else {
                m_encryptedPassword = encryptedPassword.toCharArray();
            }
        }
    }

    /**
     * This method will return the decrypted password. This method should
     * only be called by the Mapping Workbench.
     *
     * @return decryptedPassword
     */
    public String getPassword() {
        return m_securableObjectHolder.getSecurableObject().decryptPassword(getEncryptedPassword());
    }

    /**
     * Assume the password has been encrypted and return it.
     *
     * @return encryptedPassword
     */
    public String getEncryptedPassword() {
        // Bug 4117441 - Secure programming practices, store password in char[]
        if (m_encryptedPassword != null) {
            return new String(m_encryptedPassword);
        } else {
            // respect explicit de-referencing of password
            return null;
        }
    }

    public void setTableQualifier(String tableQualifier) {
        m_tableQualifier = tableQualifier;
    }

    public String getTableQualifier() {
        return m_tableQualifier;
    }

    public void setExternalConnectionPooling(boolean externalConnectionPooling) {
        m_externalConnectionPooling = externalConnectionPooling;
    }

    public boolean getExternalConnectionPooling() {
        return m_externalConnectionPooling;
    }

    public void setExternalTransactionController(boolean externalTransactionController) {
        m_externalTransactionController = externalTransactionController;
    }

    public boolean getExternalTransactionController() {
        return m_externalTransactionController;
    }

    public void setSequencingConfig(SequencingConfig sequencingConfig) {
        m_sequencingConfig = sequencingConfig;
    }

    public SequencingConfig getSequencingConfig() {
        return m_sequencingConfig;
    }

    public void setPropertyConfigs(Vector propertyConfigs) {
        m_propertyConfigs = propertyConfigs;
    }

    public Vector getPropertyConfigs() {
        return m_propertyConfigs;
    }
}
