/*
 * 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
     *
     */
    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());
    }

}
