/*
 * 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:
//     dclarke - Dynamic Persistence
//       http://wiki.eclipse.org/EclipseLink/Development/Dynamic
//       (https://bugs.eclipse.org/bugs/show_bug.cgi?id=200045)
//             - initial JPA Employee example using XML (bug 217884)
//                  ported from earlier Oracle TopLink examples
//     mnorman - tweaks to work from Ant command-line,
//               get database properties from System, etc.
//
package org.eclipse.persistence.testing.tests.dynamic;

//javase imports
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

//EclipseLink imports
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.logging.DefaultSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;

/**
 *
 * @author dclarke
 * @since EclipseLink 1.1.2
 */
public class QuerySQLTracker extends SessionEventAdapter {
    private List<QueryResult> queries;

    /**
     * Constructs and installs the event listener and sql tracking session log
     *
     * @param session
     */
    private QuerySQLTracker(Session session) {
        session.getEventManager().addListener(this);
        session.setSessionLog(new SQLTrackingSessionLog(session, this));
        reset();
    }

    public static QuerySQLTracker install(Session session) {
        if (session.getSessionLog() instanceof SQLTrackingSessionLog) {
            return ((SQLTrackingSessionLog) session.getSessionLog())
                    .getTracker();
        }
        return new QuerySQLTracker(session);
    }

    /**
     * Helper method to retrieve a tracker from a session where it was installed
     * If the session exists but does not have a tracler installed then an
     * exception is thrown.
     */
    public static QuerySQLTracker getTracker(Session session) {
        if (session == null) {
            return null;
        }
        SessionLog sessionLog = session.getSessionLog();

        if (sessionLog instanceof QuerySQLTracker.SQLTrackingSessionLog) {
            return ((QuerySQLTracker.SQLTrackingSessionLog) sessionLog)
                    .getTracker();
        }
        throw new RuntimeException(
                "Could not retireve QuerySQLTracke from session: " + session);
    }

    /**
     * Reset the lists of SQL and queries being tracked
     */
    public void reset() {
        this.queries = new ArrayList<QueryResult>();
    }

    public List<QueryResult> getQueries() {
        return this.queries;
    }

    protected QuerySQLTracker.QueryResult getCurrentResult() {
        if (getQueries().size() == 0) {
            getQueries().add(new QueryResult(null));
            // throw new RuntimeException("Received SQL without a Query ???");
        }
        return getQueries().get(getQueries().size() - 1);
    }

    public int getTotalSQLCalls() {
        int totalSQLCalls = 0;

        for (QueryResult result : getQueries()) {
            totalSQLCalls += result.sqlStatements.size();
        }

        return totalSQLCalls;
    }

    public int getTotalSQLCalls(String startsWith) {
        int sqlCalls = 0;

        for (QueryResult result : getQueries()) {
            for (String sql : result.sqlStatements) {
                String sub = sql.substring(0, startsWith.length());
                if (sub.equalsIgnoreCase(startsWith)) {
                    sqlCalls++;
                }
            }
        }

        return sqlCalls;
    }

    public int getTotalSQLSELECTCalls() {
        return getTotalSQLCalls("SELECT");
    }

    public int getTotalSQLINSERTCalls() {
        return getTotalSQLCalls("INSERT");
    }

    public int getTotalSQLUPDATECalls() {
        return getTotalSQLCalls("UPDATE");
    }

    public int getTotalSQLDELETECalls() {
        return getTotalSQLCalls("DELETE");
    }

    @Override
    public void preExecuteQuery(SessionEvent event) {
        //System.err.println("*** QuerySQLTracker.preExecuteQuery(" + event.getQuery() + ")");
        //Thread.dumpStack();
        QueryResult result = new QueryResult(event.getQuery());
        getQueries().add(result);
    }

    @Override
    public void postExecuteQuery(SessionEvent event) {
        if (getCurrentResult().query == null) {
            getCurrentResult().setQuery(event.getQuery());
        }
        getCurrentResult().setResult(event.getResult());
    }

    protected class QueryResult {
        private DatabaseQuery query;
        private String resultString = null;
        private List<String> sqlStatements = new ArrayList<String>();

        QueryResult(DatabaseQuery q) {
            query = q;
        }

        protected void setQuery(DatabaseQuery query) {
            this.query = query;
        }

        @SuppressWarnings("unchecked")
        protected void setResult(Object queryResult) {
            StringWriter writer = new StringWriter();
            writer.write(Helper.getShortClassName(query));
            writer.write("[" + System.identityHashCode(query) + "]");
            writer.write(" result = ");

            Object result = queryResult;
            if (queryResult instanceof Collection) {
                result = ((Collection) queryResult).toArray();
            }

            if (result == null) {
                writer.write("NONE");
            } else {
                if (result instanceof Object[]) {
                    Object[] results = (Object[]) result;
                    writer.write("<" + results.length + "> [");
                    for (int index = 0; index < results.length; index++) {
                        if (index > 0) {
                            writer.write(", ");
                        }
                        writer.write(results[index] + "");
                    }
                    writer.write("]");
                    resultString = writer.toString();
                } else {
                    writer.write(result.toString());
                }
            }

            this.resultString = writer.toString();
        }

        public void addSQL(String sql) {
            sqlStatements.add(sql);
        }

        public String toString() {
            if (this.resultString == null) {
                setResult(null);
            }
            return this.resultString;
        }
    }

    /**
     * This custom SessionLog implementation wraps the existing one and redirects
     * all SQL calls to the tracker. All messages are also passed to the original
     * tracker.
     */
    public class SQLTrackingSessionLog extends DefaultSessionLog {

        private QuerySQLTracker tracker;

        private SessionLog originalLog;

        protected SQLTrackingSessionLog(Session session,
                QuerySQLTracker aTracker) {
            this.tracker = aTracker;
            this.originalLog = session.getSessionLog();
            setSession(session);
            setWriter(this.originalLog.getWriter());
        }

        public QuerySQLTracker getTracker() {
            return this.tracker;
        }

        @Override
        public synchronized void log(SessionLogEntry entry) {

            if (entry.getNameSpace() != null
                    && entry.getNameSpace().equalsIgnoreCase(SessionLog.SQL)) {
                getTracker().getCurrentResult().addSQL(entry.getMessage());
            }
            super.log(entry);
        }

        @Override
        public int getLevel(String category) {
            return this.originalLog.getLevel(category);
        }

        @Override
        public void setLevel(int level, String category) {
            this.originalLog.setLevel(level, category);
        }

        @Override
        public int getLevel() {
            return this.originalLog.getLevel();
        }

        @Override
        public void setLevel(int level) {
            this.originalLog.setLevel(level);
        }

        @Override
        public boolean shouldPrintConnection() {
            return this.originalLog.shouldPrintConnection();
        }

        @Override
        public boolean shouldPrintDate() {
            return this.originalLog.shouldPrintDate();
        }

        @Override
        public boolean shouldPrintSession() {
            return this.originalLog.shouldPrintSession();
        }

        @Override
        public boolean shouldPrintThread() {
            return this.originalLog.shouldPrintThread();
        }
    }

    public void printResults(String prefix) {
        System.out.println(prefix + "-QuerySQLTracker-Queries:");

        int sql = 0;
        for (int index = 0; index < getQueries().size(); index++) {
            QueryResult result = getQueries().get(index);

            System.out.println("\t" + (index + 1) + "> " + result);

            for (int sqlNum = 0; sqlNum < result.sqlStatements.size(); sqlNum++) {
                sql++;
                System.out.println("\t\t" + (index + 1) + "." + (sqlNum + 1)
                        + "-" + sql + "> " + result.sqlStatements.get(sqlNum));
            }
        }

        System.out.println(prefix + "-QuerySQLTracker-Queries: "
                + getQueries().size());
        System.out.println(prefix + "-QuerySQLTracker-INSERT: "
                + getTotalSQLINSERTCalls());
        System.out.println(prefix + "-QuerySQLTracker-SELECT: "
                + getTotalSQLSELECTCalls());
        System.out.println(prefix + "-QuerySQLTracker-UPDATE: "
                + getTotalSQLUPDATECalls());
        System.out.println(prefix + "-QuerySQLTracker-DELETE: "
                + getTotalSQLDELETECalls());
    }

}
