/*
 * 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.exceptions;

import java.io.StringWriter;
import java.sql.SQLException;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator;
import org.eclipse.persistence.sessions.Record;

/**
 * <P><B>Purpose</B>:
 * Wrapper for any database exception that occurred through EclipseLink.
 */
public class DatabaseException extends EclipseLinkException {
    protected SQLException exception;
    protected transient Call call;
    protected transient DatabaseQuery query;
    protected transient AbstractRecord queryArguments;
    protected transient Accessor accessor;
    protected boolean isCommunicationFailure;

    public static final int SQL_EXCEPTION = 4002;
    public static final int CONFIGURATION_ERROR_CLASS_NOT_FOUND = 4003;
    public static final int DATABASE_ACCESSOR_NOT_CONNECTED = 4005;
    public static final int ERROR_READING_BLOB_DATA = 4006;
    public static final int COULD_NOT_CONVERT_OBJECT_TYPE = 4007;
    public static final int LOGOUT_WHILE_TRANSACTION_IN_PROGRESS = 4008;
    public static final int SEQUENCE_TABLE_INFORMATION_NOT_COMPLETE = 4009;
    public static final int ERROR_PREALLOCATING_SEQUENCE_NUMBERS = 4011;
    public static final int CANNOT_REGISTER_SYNCHRONIZATIONLISTENER_FOR_UNITOFWORK = 4014;
    public static final int SYNCHRONIZED_UNITOFWORK_DOES_NOT_SUPPORT_COMMITANDRESUME = 4015;
    public static final int CONFIGURATION_ERROR_NEW_INSTANCE_INSTANTIATION_EXCEPTION = 4016;
    public static final int CONFIGURATION_ERROR_NEW_INSTANCE_ILLEGAL_ACCESS_EXCEPTION = 4017;
    public static final int TRANSACTION_MANAGER_NOT_SET_FOR_JTS_DRIVER = 4018;
    public static final int ERROR_RETRIEVE_DB_METADATA_THROUGH_JDBC_CONNECTION = 4019;
    public static final int COULD_NOT_FIND_MATCHED_DATABASE_FIELD_FOR_SPECIFIED_OPTOMISTICLOCKING_FIELDS = 4020;
    public static final int UNABLE_TO_ACQUIRE_CONNECTION_FROM_DRIVER = 4021;
    public static final int DATABASE_ACCESSOR_CONNECTION_IS_NULL = 4022;

    /**
     * INTERNAL:
     * EclipseLink exceptions should only be thrown by the EclipseLink code.
     */
    protected DatabaseException() {
    }

    /**
     * INTERNAL:
     * EclipseLink exceptions should only be thrown by the EclipseLink code.
     */
    protected DatabaseException(String message) {
        super(message);
    }

    /**
     * INTERNAL:
     * EclipseLink exceptions should only be thrown by the EclipseLink code.
     */
    protected DatabaseException(SQLException exception) {
        super(exception.toString(), exception);
    }

    public static DatabaseException cannotRegisterSynchronizatonListenerForUnitOfWork(Exception e) {
        Object[] args = { e };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, CANNOT_REGISTER_SYNCHRONIZATIONLISTENER_FOR_UNITOFWORK, args));
        databaseException.setErrorCode(CANNOT_REGISTER_SYNCHRONIZATIONLISTENER_FOR_UNITOFWORK);
        databaseException.setInternalException(e);
        return databaseException;
    }

    public static DatabaseException configurationErrorClassNotFound(String className) {
        Object[] args = { className };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, CONFIGURATION_ERROR_CLASS_NOT_FOUND, args));
        databaseException.setErrorCode(CONFIGURATION_ERROR_CLASS_NOT_FOUND);
        return databaseException;
    }

    public static DatabaseException configurationErrorNewInstanceIllegalAccessException(IllegalAccessException exception, Class javaClass) {
        Object[] args = { javaClass };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, CONFIGURATION_ERROR_NEW_INSTANCE_ILLEGAL_ACCESS_EXCEPTION, args));
        databaseException.setErrorCode(CONFIGURATION_ERROR_NEW_INSTANCE_ILLEGAL_ACCESS_EXCEPTION);
        databaseException.setInternalException(exception);
        return databaseException;
    }

    public static DatabaseException configurationErrorNewInstanceInstantiationException(InstantiationException exception, Class javaClass) {
        Object[] args = { javaClass };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, CONFIGURATION_ERROR_NEW_INSTANCE_INSTANTIATION_EXCEPTION, args));
        databaseException.setErrorCode(CONFIGURATION_ERROR_NEW_INSTANCE_INSTANTIATION_EXCEPTION);
        databaseException.setInternalException(exception);
        return databaseException;
    }

    public static DatabaseException couldNotConvertObjectType(int type) {
        Object[] args = { CR, type};

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, COULD_NOT_CONVERT_OBJECT_TYPE, args));
        databaseException.setErrorCode(COULD_NOT_CONVERT_OBJECT_TYPE);
        return databaseException;
    }

    public static DatabaseException databaseAccessorNotConnected() {
        Object[] args = {  };
        String message = org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator.buildMessage(DatabaseException.class, DATABASE_ACCESSOR_NOT_CONNECTED, args);
        DatabaseException databaseException = new DatabaseException(message);
        databaseException.setErrorCode(DATABASE_ACCESSOR_NOT_CONNECTED);
        return databaseException;
    }

    public static DatabaseException databaseAccessorNotConnected(DatabaseAccessor databaseAccessor) {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, DATABASE_ACCESSOR_NOT_CONNECTED, args));
        databaseException.setErrorCode(DATABASE_ACCESSOR_NOT_CONNECTED);
        databaseException.setAccessor(databaseAccessor);
        return databaseException;
    }

    public static DatabaseException databaseAccessorConnectionIsNull(DatabaseAccessor databaseAccessor, AbstractSession session) {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, DATABASE_ACCESSOR_CONNECTION_IS_NULL, args));
        databaseException.setErrorCode(DATABASE_ACCESSOR_CONNECTION_IS_NULL);
        databaseException.setAccessor(databaseAccessor);
        databaseException.setSession(session);
        return databaseException;
    }

    public static DatabaseException errorPreallocatingSequenceNumbers() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, ERROR_PREALLOCATING_SEQUENCE_NUMBERS, args));
        databaseException.setErrorCode(ERROR_PREALLOCATING_SEQUENCE_NUMBERS);
        return databaseException;
    }

    public static DatabaseException errorReadingBlobData() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, ERROR_READING_BLOB_DATA, args));
        databaseException.setErrorCode(ERROR_READING_BLOB_DATA);
        return databaseException;
    }

    public static DatabaseException specifiedLockingFieldsNotFoundInDatabase(String lockingFieldName) {
        Object[] args = { lockingFieldName };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, COULD_NOT_FIND_MATCHED_DATABASE_FIELD_FOR_SPECIFIED_OPTOMISTICLOCKING_FIELDS, args));
        databaseException.setErrorCode(COULD_NOT_FIND_MATCHED_DATABASE_FIELD_FOR_SPECIFIED_OPTOMISTICLOCKING_FIELDS);
        return databaseException;
    }


    /**
     *    PUBLIC:
     *    Return the accessor.
     */
    public Accessor getAccessor() {
        return accessor;
    }

    /**
     * PUBLIC:
     * This is the database error number.
     * Since it is possible to have no internal exception the errorCode will be zero in this case.
     */
    public int getDatabaseErrorCode() {
        if (getInternalException() == null) {
            return super.getErrorCode();
        }
        return ((SQLException)getInternalException()).getErrorCode();
    }

    /**
     * PUBLIC:
     * This is the database error message.
     */
    @Override
    public String getMessage() {
        if (getInternalException() == null) {
            return super.getMessage();
        } else {
            StringWriter writer = new StringWriter();
            writer.write(super.getMessage());
            writer.write(cr());
            writer.write(getIndentationString());
            writer.write(ExceptionMessageGenerator.getHeader("ErrorCodeHeader"));
            if (getInternalException() instanceof SQLException) {
                writer.write(Integer.toString(((SQLException)getInternalException()).getErrorCode()));
            } else {
                writer.write("000");
            }
            if (getCall() != null) {
                writer.write(cr());
                writer.write(getIndentationString());
                writer.write(ExceptionMessageGenerator.getHeader("CallHeader"));
                if (getAccessor() != null) {
                    writer.write(getCall().getLogString(getAccessor()));
                } else {
                    writer.write(getCall().toString());
                }
            }
            if (getQuery() != null) {
                writer.write(cr());
                writer.write(getIndentationString());
                writer.write(ExceptionMessageGenerator.getHeader("QueryHeader"));
                try {
                    writer.write(getQuery().toString());
                } catch (RuntimeException badTooString) {
                }
            }
            return writer.toString();
        }
    }

    /**
     *    PUBLIC:
     *    This method returns the databaseQuery.
     *    DatabaseQuery is a visible class to the EclipseLink user.
     *    Users create an appropriate query by creating an instance
     *    of a concrete subclasses of DatabaseQuery.
     */
    public DatabaseQuery getQuery() {
        return query;
    }

    /**
     *    PUBLIC:
     *    Return the call that caused the exception.
     */
    public Call getCall() {
        return call;
    }

    /**
     *    INTERNAL:
     *    Set the call that caused the exception.
     */
    public void setCall(Call call) {
        this.call = call;
    }

    /**
     * PUBLIC:
     * Return the query arguments used in the original query when exception is thrown
     */
    public Record getQueryArgumentsRecord() {
        return queryArguments;
    }

    public static DatabaseException logoutWhileTransactionInProgress() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, LOGOUT_WHILE_TRANSACTION_IN_PROGRESS, args));
        databaseException.setErrorCode(LOGOUT_WHILE_TRANSACTION_IN_PROGRESS);
        return databaseException;
    }

    public static DatabaseException sequenceTableInformationNotComplete() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, SEQUENCE_TABLE_INFORMATION_NOT_COMPLETE, args));
        databaseException.setErrorCode(SEQUENCE_TABLE_INFORMATION_NOT_COMPLETE);
        return databaseException;
    }

    /**
     *    INTERNAL:
     *  Set the Accessor.
     */
    public void setAccessor(Accessor accessor) {
        this.accessor = accessor;
    }

    /**
     *    PUBLIC:
     *    This method set the databaseQuery.
     *    DatabaseQuery is a visible class to the EclipseLink user.
     *    Users create an appropriate query by creating an instance
     *    of a concrete subclasses of DatabaseQuery.
     */
    public void setQuery(DatabaseQuery query) {
        this.query = query;
    }

    /**
     * PUBLIC:
     * Set the query arguments used in the original query when exception is thrown
     */
    public void setQueryArguments(AbstractRecord queryArguments) {
        this.queryArguments = queryArguments;
    }

    public static DatabaseException sqlException(SQLException exception) {
        return sqlException(exception, false);
    }

    public static DatabaseException sqlException(SQLException exception, boolean commError) {
        DatabaseException databaseException = new DatabaseException(exception);
        databaseException.setErrorCode(SQL_EXCEPTION);
        databaseException.setCommunicationFailure(commError);
        return databaseException;
    }

    public static DatabaseException sqlException(SQLException exception, AbstractSession session, boolean commError) {
        if (session == null) {
            return sqlException(exception, commError);
        } else {
            return sqlException(exception, session.getAccessor(), session, commError);
        }
    }

    public static DatabaseException sqlException(SQLException exception, Accessor accessor, AbstractSession session, boolean isCommunicationFailure) {
        DatabaseException databaseException = new DatabaseException(exception);
        databaseException.setErrorCode(SQL_EXCEPTION);
        databaseException.setAccessor(accessor);
        databaseException.setSession(session);
        databaseException.setCommunicationFailure(isCommunicationFailure);
        return databaseException;
    }

    public static DatabaseException sqlException(SQLException exception, Call call, Accessor accessor, AbstractSession session, boolean isCommunicationFailure) {
        DatabaseException databaseException = new DatabaseException(exception);
        databaseException.setErrorCode(SQL_EXCEPTION);
        databaseException.setAccessor(accessor);
        databaseException.setCall(call);
        databaseException.setCommunicationFailure(isCommunicationFailure);
        return databaseException;
    }

    public static DatabaseException synchronizedUnitOfWorkDoesNotSupportCommitAndResume() {
        Object[] args = {  };

        String message = org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator.buildMessage(DatabaseException.class, SYNCHRONIZED_UNITOFWORK_DOES_NOT_SUPPORT_COMMITANDRESUME, args);
        DatabaseException databaseException = new DatabaseException(message);
        databaseException.setErrorCode(SYNCHRONIZED_UNITOFWORK_DOES_NOT_SUPPORT_COMMITANDRESUME);
        return databaseException;
    }

    public static DatabaseException transactionManagerNotSetForJTSDriver() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, TRANSACTION_MANAGER_NOT_SET_FOR_JTS_DRIVER, args));
        databaseException.setErrorCode(TRANSACTION_MANAGER_NOT_SET_FOR_JTS_DRIVER);
        return databaseException;
    }

    public static DatabaseException errorRetrieveDbMetadataThroughJDBCConnection() {
        Object[] args = {  };

        DatabaseException databaseException = new DatabaseException(ExceptionMessageGenerator.buildMessage(DatabaseException.class, ERROR_RETRIEVE_DB_METADATA_THROUGH_JDBC_CONNECTION, args));
        databaseException.setErrorCode(ERROR_RETRIEVE_DB_METADATA_THROUGH_JDBC_CONNECTION);
        return databaseException;
    }

    /**
     * The connection returned from this driver was null, the driver may be
     * missing(using the default) or the wrong one for the database.
     *
     */
    public static DatabaseException unableToAcquireConnectionFromDriverException(
            String driver, String user, String url) {
        Object[] args = { driver, user, url };
        DatabaseException databaseException = new DatabaseException(
                ExceptionMessageGenerator.buildMessage(DatabaseException.class,
                        UNABLE_TO_ACQUIRE_CONNECTION_FROM_DRIVER, args));
        databaseException.setErrorCode(UNABLE_TO_ACQUIRE_CONNECTION_FROM_DRIVER);
        return databaseException;
    }

    /**
     * The connection returned from this driver was null, the driver may be
     * missing(using the default) or the wrong one for the database.
     *
     */
    public static DatabaseException unableToAcquireConnectionFromDriverException(SQLException exception,
            String driver, String user, String url) {
        DatabaseException databaseException = unableToAcquireConnectionFromDriverException(driver, user, url);
        databaseException.setInternalException(exception);
        return databaseException;
    }

    public boolean isCommunicationFailure() {
        return isCommunicationFailure;
    }

    public void setCommunicationFailure(boolean isCommunicationFailure) {
        this.isCommunicationFailure = isCommunicationFailure;
    }

}
