/*
 * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2021 IBM Corporation. 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:
//     July 13, 2011 - Andrei Ilitchev (Oracle) - initial API and implementation
package org.eclipse.persistence.testing.framework;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.SessionEventManager;

/**
 * <p><b>Purpose</b>: Used to test handling of session events.
 *
 * Create several instances of the class;
 * name them to distinguish from each other;
 * add them to different sessions' EventManagers.
 *
 * In the test:
 *   // clear the previously logged event handlings
 *   SessionEventTracker.clearLog();
 *   // define which events should be tracked, for instance:
 *   // first clear all the previously set events,
 *   SessionEventTracker.noneEvents();
 *   // then add events to be tracked:
 *   SessionEventTracker.addEvent(SessionEvent.PreLogin);
 *   SessionEventTracker.addEvent(SessionEvent.PostLogin);
 *   // start tracking
 *   SessionEventTracker.startTracking();
 *
 *   // do something
 *
 *   SessionEventTracker.stopTracking();
 *   // analyze listeners and events Lists.
 *
 *   clean up (optional)
 *   SessionEventTracker.clearLog();
 *   // return back to the default setting - handling all events
 *   SessionEventTracker.allEvents();
 *
 *   In static handlings list contains instances of Handling class -
 *   each holds an event and a listener that has handled it.
 *
 *   It's possible to set error on a Handling (see examples preLogin and postLogin) -
 *   that sends the erroneous Handling to errors list (still kept on handlings list, too).
 *
 * @see SessionEventManager#addListener(SessionEventListener)
 * @see Session#getEventManager()
 * @see SessionEvent
 */
public class SessionEventTracker implements SessionEventListener {

    // in order from 1 to (currently) 35 (no holes!).
    // should be kept in sync with SessionEvent codes.
    public static final String[] eventNames = {
        "PreExecuteQuery ",
        "PostExecuteQuery",
        "PreBeginTransaction",
        "PostBeginTransaction",
        "PreCommitTransaction",
        "PostCommitTransaction",
        "PreRollbackTransaction",
        "PostRollbackTransaction",
        "PostAcquireUnitOfWork",
        "PreCommitUnitOfWork",
        "PostCommitUnitOfWork",
        "PreReleaseUnitOfWork",
        "PostReleaseUnitOfWork",
        "PrepareUnitOfWork",
        "PostResumeUnitOfWork",
        "PostAcquireClientSession",
        "PreReleaseClientSession",
        "PostReleaseClientSession",
        "OutputParametersDetected",
        "MoreRowsDetected",
        "PostConnect",
        "PostAcquireConnection",
        "PreReleaseConnection",
        "PreLogin",
        "PostLogin",
        "PreMergeUnitOfWorkChangeSet",
        "PreDistributedMergeUnitOfWorkChangeSet",
        "PostMergeUnitOfWorkChangeSet",
        "PostDistributedMergeUnitOfWorkChangeSet",
        "PreCalculateUnitOfWorkChangeSet",
        "PostCalculateUnitOfWorkChangeSet",
        "MissingDescriptor",
        "PostAcquireExclusiveConnection",
        "PreReleaseExclusiveConnection",
        "NoRowsModified"
    };

    public static int nEvents = eventNames.length;

    public static boolean isTracking;
    public static boolean[] shouldTrackEvent = new boolean[nEvents];
    static {
        allEvents();
    }

    public static class Handling {
        public Handling(SessionEventTracker listener, SessionEvent event) {
            this.time = System.currentTimeMillis();
            this.listener = listener;
            this.event = event;
        }
        long time;
        SessionEventTracker listener;
        SessionEvent event;
        String error = "";
        public String toString() {
            return listener.name + " -> " + eventToString(event) + (error.length()==0 ? "" : " Error: " + error);
        }
        public void setError(String error) {
            this.error = error;
            if (error.length() > 0) {
                synchronized (errors) {
                    errors.add(this);
                }
            } else {
                synchronized (errors) {
                    errors.remove(this);
                }
            }
        }
        public String getError() {
            return error;
        }
        public SessionEvent getEvent() {
            return event;
        }
        public SessionEventTracker getListener() {
            return listener;
        }
    }

    protected static List<Handling> handlings = new ArrayList();
    protected static List<Handling> errors = new ArrayList();

    protected String name = "";

    public SessionEventTracker() {
        super();
    }

    public SessionEventTracker(String name) {
        this.name = name;
    }

    public static void startTracking() {
        isTracking = true;
    }

    public static void stopTracking() {
        isTracking = false;
    }

    public static boolean isTracking() {
        return isTracking;
    }

    public static boolean isTrackingEvent(SessionEvent event) {
        if (isTracking) {
            return shouldTrackEvent[event.getEventCode()];
        } else {
            return false;
        }
    }

    public static int size() {
        return handlings.size();
    }

    public static void clearLog() {
        handlings = new ArrayList();
        errors = new ArrayList();
    }

    public static void allEvents() {
        for (int i=1; i<nEvents; i++) {
            shouldTrackEvent[i] = true;
        }
    }

    public static void noneEvents() {
        for (int i=1; i<nEvents; i++) {
            shouldTrackEvent[i] = false;
        }
    }

    public static void addEvent(int eventCode) {
        if (eventCode <= 0) {
            throw new TestErrorException("event code " + eventCode + " is wrong - should be a positive number");
        } else if (eventCode > eventNames.length) {
            throw new TestErrorException("event code " + eventCode + " is unknown - add event name for it to SessionEventTracker.eventNames array");
        }
        shouldTrackEvent[eventCode] = true;
    }

    public static void removeEvent(int eventCode) {
        if (eventCode <= 0) {
            throw new TestErrorException("event code " + eventCode + " is wrong - should be a positive number");
        } else if (eventCode > eventNames.length) {
            throw new TestErrorException("event code " + eventCode + " is unknown - add event name for it to SessionEventTracker.eventNames array");
        }
        shouldTrackEvent[eventCode] = false;
    }

    public static List<Handling> getHandlings() {
        return handlings;
    }

    public static List<Handling> getErrors() {
        return errors;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * PUBLIC:
     * This event is raised on the session if a descriptor is missing for a class being persisted.
     * This can be used to lazy register the descriptor or set of descriptors.
     */
    @Override
    public void missingDescriptor(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the session after read object query detected more than a single row back from the database.
     * The "result" of the event will be the call.  Some applications may want to interpret this as an error or warning condition.
     */
    @Override
    public void moreRowsDetected(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the session after update or delete SQL has been sent to the database
     * but a row count of zero was returned.
     */
    @Override
    public void noRowsModified(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the session after a stored procedure call has been executed that had output parameters.
     * If the proc was used to override an insert/update/delete operation then EclipseLink will not be expecting any return value.
     * This event mechanism allows for a listener to be registered before the proc is call to process the output values.
     * The event "result" will contain a Record of the output values, and property "call" will be the StoredProcedureCall.
     */
    @Override
    public void outputParametersDetected(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the client session after creation/acquiring.
     */
    @Override
    public void postAcquireClientSession(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on when using the server/client sessions.
     * This event is raised after a connection is acquired from a connection pool.
     */
    @Override
    public void postAcquireConnection(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised when a ClientSession, with Isolated data, acquires
     * an exclusive connection.  The event will contain the ClientSession that
     * is being acquired.  Users can set properties within the ConnectionPolicy
     * of that ClientSession for access within this event.
     */
    @Override
    public void postAcquireExclusiveConnection(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work after creation/acquiring.
     * This will be raised on nest units of work.
     */
    @Override
    public void postAcquireUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after a database transaction is started.
     * It is not raised for nested transactions.
     */
    @Override
    public void postBeginTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after the commit has begun on the UnitOfWork but before
     * the changes are calculated.
     */
    @Override
    public void preCalculateUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after the commit has begun on the UnitOfWork and
     * after the changes are calculated.  The UnitOfWorkChangeSet, at this point,
     * will contain changeSets without the version fields updated and without
     * IdentityField type primary keys.  These will be updated after the insert, or
     * update, of the object
     */
    @Override
    public void postCalculateUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after a database transaction is commited.
     * It is not raised for nested transactions.
     */
    @Override
    public void postCommitTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work after commit.
     * This will be raised on nest units of work.
     */
    @Override
    public void postCommitUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after the session connects to the database.
     * In a server session this event is raised on every new connection established.
     */
    @Override
    public void postConnect(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after the execution of every query against the session.
     * The event contains the query and query result.
     */
    @Override
    public void postExecuteCall(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after the execution of every query against the session.
     * The event contains the query and query result.
     */
    @Override
    public void postExecuteQuery(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the client session after releasing.
     */
    @Override
    public void postReleaseClientSession(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work after release.
     * This will be raised on nest units of work.
     */
    @Override
    public void postReleaseUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work after resuming.
     * This occurs after pre/postCommit.
     */
    @Override
    public void postResumeUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised after a database transaction is rolledback.
     * It is not raised for nested transactions.
     */
    @Override
    public void postRollbackTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This even will be raised after a UnitOfWorkChangeSet has been merged
     * When that changeSet has been received from a distributed session
     */
    @Override
    public void postDistributedMergeUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This even will be raised after a UnitOfWorkChangeSet has been merged
     */
    @Override
    public void postMergeUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised before a database transaction is started.
     * It is not raised for nested transactions.
     */
    @Override
    public void preBeginTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised before a database transaction is commited.
     * It is not raised for nested transactions.
     */
    @Override
    public void preCommitTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work before commit.
     * This will be raised on nest units of work.
     */
    @Override
    public void preCommitUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised before the execution of every query against the session.
     * The event contains the query to be executed.
     */
    @Override
    public void preExecuteCall(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised before the execution of every query against the session.
     * The event contains the query to be executed.
     */
    @Override
    public void preExecuteQuery(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work after the SQL has been flushed, but the commit transaction has not been executed.
     * It is similar to the JTS prepare phase.
     */
    @Override
    public void prepareUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the client session before releasing.
     */
    @Override
    public void preReleaseClientSession(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on when using the server/client sessions.
     * This event is raised before a connection is released into a connection pool.
     */
    @Override
    public void preReleaseConnection(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is fired just before a Client Session, with isolated data,
     * releases its Exclusive Connection
     */
    @Override
    public void preReleaseExclusiveConnection(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised on the unit of work before release.
     * This will be raised on nest units of work.
     */
    @Override
    public void preReleaseUnitOfWork(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This event is raised before a database transaction is rolledback.
     * It is not raised for nested transactions.
     */
    @Override
    public void preRollbackTransaction(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This even will be raised before a UnitOfWorkChangeSet has been merged
     * When that changeSet has been received from a distributed session
     */
    @Override
    public void preDistributedMergeUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This even will be raised before a UnitOfWorkChangeSet has been merged
     */
    @Override
    public void preMergeUnitOfWorkChangeSet(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This Event is raised before the session logs in.
     */
    @Override
    public void preLogin(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        Handling handling = log(event);
        if (((DatabaseSessionImpl)event.getSession()).isLoggedIn()) {
            handling.setError("session is already logged in");
        }
    }

    /**
     * PUBLIC:
     * This Event is raised after the session logs out.
     */
    @Override
    public void preLogout(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This Event is raised after the session logs out.
     */
    @Override
    public void postLogout(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        log(event);
    }

    /**
     * PUBLIC:
     * This Event is raised after the session logs in.
     */
    @Override
    public void postLogin(SessionEvent event) {
        if (!isTrackingEvent(event)) {
            return;
        }
        Handling handling = log(event);
        String errorMsg = "";
        Iterator<ClassDescriptor> it = event.getSession().getDescriptors().values().iterator();
        while (it.hasNext()) {
            ClassDescriptor descriptor = it.next();
            if (!descriptor.isAggregateDescriptor()) {
                if (!descriptor.isFullyInitialized()) {
                    errorMsg += descriptor.getJavaClass().getName() + "; ";
                }
            }
        }
        if (errorMsg.length() > 0) {
            errorMsg = "Some descriptors are not initialized: " + errorMsg;
            handling.setError(errorMsg);
        }
    }

    protected Handling log(SessionEvent event) {
        Handling handling = new Handling(this, event);
        synchronized (handlings) {
            handlings.add(handling);
        }
        return handling;
    }

    public String toString() {
        return Helper.getShortClassName(this) + "(" + (name != null ? name : "") + ")";
    }

    public static String eventToString(SessionEvent event) {
        return getEventName(event.getEventCode()) + "[" + sessionToString(event.getSession()) + "]";
    }

    public static String getEventName(int eventCode) {
        if (eventCode <= 0) {
            throw new TestErrorException("event code " + eventCode + " is wrong - should be a positive number");
        } else if (eventCode > eventNames.length) {
            throw new TestErrorException("event code " + eventCode + " is unknown - add event name for it to SessionEventTracker.eventNames array");
        }
        return eventNames[eventCode - 1];
    }

    public static String sessionToString(Session session) {
        return Helper.getShortClassName(session) + "(" + session.getName() + ")";
    }
}
