/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Mike Norman - from Proof-of-concept, become production code
 ******************************************************************************/
package dbws.testing.shadowddlgeneration.oldjpub;

//javase imports
import java.io.Externalizable;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutput;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

//EclipseLink imports
import dbws.testing.shadowddlgeneration.oldjpub.MethodFilter;
import dbws.testing.shadowddlgeneration.oldjpub.Util;
import dbws.testing.shadowddlgeneration.oldjpub.OracleTypes;
import dbws.testing.shadowddlgeneration.oldjpub.SqlName;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_ARGUMENTS;

@SuppressWarnings({"unchecked","rawtypes"})
public class ViewCache implements Externalizable {

    static final String VIEW_CACHE_PREFIX = "viewcachefor";
    public static final String PARAMETER_USER = "USER";
    public static final String PARAMETER_ALL = "ALL";

    protected Connection m_conn;
    protected String m_user;
    protected Map m_rowsCacheIndex;
    protected ArrayList m_rowsCache;
    protected int m_hits;
    protected int m_visits;
    protected boolean m_viewCacheDebug = false;

    @SuppressWarnings("unused")
    public Iterator<ViewRow> getRows(String view, String[] columns, String[] keys, Object[] values,
        String[] orderby) throws java.sql.SQLException {
        m_visits++;
        String cKey = makeKey(view, columns, keys, values, orderby);
        ArrayList rowsV = (ArrayList)m_rowsCacheIndex.get(cKey);
        ArrayList derivedRowsV = rowsV;

        // NARROW DOWN QUERIES
        if (derivedRowsV == null) {
            for (int i = 0; i < m_rowsCache.size(); i++) {
                RowsCacheEntry incoming = new RowsCacheEntry(view, columns, keys, values, null);
                RowsCacheEntry cached = (RowsCacheEntry)m_rowsCache.get(i);
                RowsCacheEntry diff = cached.compare(incoming);
                if (diff != null) {
                    if (m_viewCacheDebug) {
                        System.out.println("viewcache.hit.query.relaxed: " + i);
                    }
                    derivedRowsV = new ArrayList();
                    for (int j = 0; j < diff.getRows().size(); j++) {
                        ViewRow row = diff.getRows().get(j);
                        boolean match = true;
                        for (int k = 0; k < diff.getKeys().length; k++) {
                            if ((k + 1) < diff.getKeys().length
                                && diff.getKeys()[k].equals(diff.getKeys()[k + 1])) {
                                if (!row.equals(diff.getKeys()[k], diff.getValues()[k])
                                    && !row.equals(diff.getKeys()[k], diff.getValues()[k])) {
                                    match = false;
                                    k++;
                                }
                            }
                            else if (!row.equals(diff.getKeys()[k], diff.getValues()[k])) {
                                match = false;
                            }
                        }
                        if (match) {
                            derivedRowsV.add(row);
                        }
                    }
                    break;
                }
                else if (m_viewCacheDebug) {
                    System.out.println("viewcache.no.match.query: " + i + ", diff=" + diff);
                }
            }
        }
        // ORDER BY SEQUENCE
        if (rowsV == null && orderby.length == 1 && orderby[0].equalsIgnoreCase(Util.SEQUENCE)
            && ViewRowFactory.hasSequence(view)) {
            if (derivedRowsV == null) {
                String unorderedCKey = makeKey(view, columns, keys, values, new String[0]);
                derivedRowsV = (ArrayList)m_rowsCacheIndex.get(unorderedCKey);
            }
            if (derivedRowsV != null) {
                rowsV = (ArrayList)derivedRowsV.clone();
                UserArguments.orderBySequence(rowsV);
                if (m_viewCacheDebug) {
                    System.out.println("viewcache.hit.query.unordered.sequence");
                }
            }
        }
        else
        // ORDER BY POSITION
        if (rowsV == null && orderby.length == 1 && orderby[0].equalsIgnoreCase("POSITION")
            && ViewRowFactory.hasPosition(view)) {
            if (derivedRowsV == null) {
                String unorderedCKey = makeKey(view, columns, keys, values, new String[0]);
                derivedRowsV = (ArrayList)m_rowsCacheIndex.get(unorderedCKey);
            }
            if (derivedRowsV != null) {
                rowsV = (ArrayList)derivedRowsV.clone();
                UserArguments.orderByPosition(rowsV);
                if (m_viewCacheDebug) {
                    System.out.println("viewcache.hit.query.unordered.position");
                }
            }
        }
        if (rowsV == null) {
            rowsV = derivedRowsV;
        }
        if (rowsV == null) {
            String stmtText = makeQuery(view, columns, keys, values, orderby);
            ResultSet rset = null;
            PreparedStatement stmt = null;
            if (m_conn == null) {
                throw new SQLException("ERROR: null JDBC connection.");
            }
            try {
                stmt = m_conn.prepareStatement(stmtText);
                long millis = 0;
                if (m_viewCacheDebug) {
                    millis = System.currentTimeMillis();
                    System.out.println("viewcache.execute.query: " + stmtText);
                }
                rset = stmt.executeQuery();
                rowsV = new ArrayList<ViewRow>();
                while (rset.next()) {
                    rowsV.add(ViewRowFactory.createViewRow(view, columns, rset));
                    if (m_viewCacheDebug) {
                        System.out.print(".");
                    }
                }
                if (m_viewCacheDebug) {
                    System.out.println("\nviewcache.execute.query.result.set.next.elapse: "
                        + (System.currentTimeMillis() - millis));
                }
            }
            finally {
                if (rset != null) {
                    rset.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
            }

            m_rowsCacheIndex.put(cKey, rowsV);
            m_rowsCache.add(new RowsCacheEntry(view, columns, keys, values, rowsV));

        }
        else {
            m_hits++;
            if (m_viewCacheDebug) {
                String stmtText = makeQuery(view, columns, keys, values, orderby);
                System.out.println("viewcache.hit.query: " + stmtText);
            }
        }

        if (rowsV == null) {
            // not found in view cache and no database connection
            rowsV = new ArrayList();
        }
        if (m_viewCacheDebug) {
            System.out.println("viewcache.execute.query.result.size: " + rowsV.size());
            System.out.println("viewcache.hit.rate: " + cKey + ", " + m_hits + "/" + m_visits);
        }
        return rowsV.iterator();
    }

    public Object[] getOutParameters(String stmtText, Object[] inParams, int[] types)
        throws SQLException {
        m_visits++;
        Object[] objTypes = toObject(types);
        String cKey = makeKey(stmtText, new String[0], new String[0], inParams, new String[0]);
        ArrayList outParamList = (ArrayList)m_rowsCacheIndex.get(cKey);
        if (outParamList == null && m_conn != null) {
            // initialize parameter list
            outParamList = new ArrayList();
            CallableStatement stmt = m_conn.prepareCall(stmtText);
            int i = 1;
            for (; i < inParams.length + 1; i++) {
                if (inParams[i - 1] instanceof byte[]) {
                    stmt.setBytes(i, (byte[])inParams[i - 1]);
                }
                else {
                    throw new SQLException("input type not supported: "
                        + inParams[i - 1].getClass().getName());
                }
            }
            for (; i < (inParams.length + types.length + 1); i++) {
                stmt.registerOutParameter(i, types[i - inParams.length - 1]);
            }
            stmt.executeUpdate();
            for (i = inParams.length; i < inParams.length + types.length; i++) {
                int index = i - inParams.length;
                if (types[index] == OracleTypes.INTEGER) {
                    outParamList.add(Integer.valueOf(stmt.getInt(i + 1)));
                }
                else if (types[index] == OracleTypes.VARCHAR) {
                    outParamList.add(stmt.getString(i + 1));
                }
            }
            stmt.close();
            m_rowsCacheIndex.put(cKey, outParamList);
            m_rowsCache.add(new RowsCacheEntry(stmtText, new String[0], new String[0], objTypes,
                outParamList));
        }

        Object[] outParams = null;
        if (outParamList != null) {
            outParams = outParamList.toArray(new Object[0]);
        }
        return outParams;
    }

    private Object[] toObject(int[] types) {
        Object[] obj = new Object[types.length];
        for (int i = 0; i < types.length; i++) {
            obj[i] = Integer.valueOf(types[i]);
        }
        return obj;
    }

    private String makeKey(String view, String[] columns, String[] keys, Object[] values,
        String[] orderby) {
        String key = view;
        if (columns.length != 0) {
            key = key + "[";
            for (int i = 0; i < columns.length; i++) {
                key += columns[i] + (i > 0 ? ", " : "");
            }
            key += "]";
        }
        key = key + "(";
        for (int i = 0; i < keys.length; i++) {
            key += keys[i] + ", ";
        }
        key += ": ";
        for (int i = 0; i < values.length; i++) {
            if (values[i] instanceof byte[]) {
                byte[] bytes = (byte[])values[i];
                for (int j = 0; j < bytes.length; j++) {
                    key += bytes[j];
                }
                key += ", ";
            }
            else {
                key += values[i] + ", ";
            }
        }
        key += ")";
        for (int i = 0; i < orderby.length; i++) {
            key += orderby[i] + "(o)";
        }
        return key.toUpperCase(); // On Windows, all keys are capitalized during deserialization
    }

    /*
     * makeQuery( "ALL_OBJECT", new String[]{"OWNER", "OBJEC_TYPE", "OBJECT_TYPE"}, new
     * String[]{"SCOTT", "PROCEDURE", "FUN%CTION"}) => WEHERE OWNER='SCOTT' AND
     * (OBJECT_TYPE='PROCEDURE OR OBJECT_TYPE like 'FUN%CTION')
     */
    private String makeQuery(String view, String[] columns, String[] keys, Object[] values,
        String[] orderby) {
        String stmt = "SELECT " + ViewRowFactory.getProject(view, columns) + " FROM " + view;
        if (keys.length > 0) {
            stmt += " WHERE ";
        }
        boolean inOR = false;
        for (int i = 0; i < keys.length; i++) {
            // OR
            if (!inOR && i < (keys.length - 1) && keys[i].equals(keys[i + 1])) {
                stmt += "(";
                inOR = true;
            }
            stmt += keys[i];
            if (values[i] == null || "".equals(values[i])) {
                stmt += " IS NULL";
            }
            else if ("NOT NULL".equals(values[i])) {
                stmt += " IS NOT NULL";
            }
            else if (values[i] instanceof java.lang.String) {
                stmt += "='" + ((java.lang.String)values[i]) + "'";
            }
            else if ((values[i] instanceof java.lang.String)
                && ((String)values[i]).indexOf("%") > -1) {
                stmt += " like '" + ((java.lang.String)values[i]) + "'";
            }
            else {
                stmt += "=" + values[i];
            }
            if (inOR && i < keys.length - 1 && keys[i].equals(keys[i + 1])) {
                stmt += " OR ";
            }
            else if (inOR && i < keys.length - 1) {
                stmt += ") AND ";
                inOR = false;
            }
            else if (inOR) {
                stmt += ")";
                inOR = false;
            }
            else if (i < keys.length - 1) {
                stmt += " AND ";
            }
        }
        for (int i = 0; i < orderby.length; i++) {
            if (i == 0) {
                stmt += " ORDER BY ";
            }
            stmt += orderby[i];
            if (i != (orderby.length - 1)) {
                stmt += ", ";
            }
        }
        return stmt;
    }

    public ViewCache() {
    }

    public ViewCache(Connection conn, String user) {
        m_conn = conn;
        m_user = user;
        m_rowsCacheIndex = new HashMap();
        m_rowsCache = new ArrayList();
        m_hits = 0;
        m_visits = 0;
    }

    /*
     * initialize the cache using queries of the viewcache passed in
     */
    public void init(ViewCache viewCache) {
        int len = m_rowsCache.size();
        for (int i = 0; i < len; i++) {
            RowsCacheEntry entry = (RowsCacheEntry)m_rowsCache.get(i);
            try {
                getRows(entry);
            }
            catch (Exception e) {
                System.err.println("WARNING: error in refreshing view cache for view "
                    + entry.getView());
            }
        }
    }

    /*
     * refresh the cache
     */
    public void refresh() {
        int len = m_rowsCache.size();
        for (int i = 0; i < len; i++) {
            RowsCacheEntry entry = (RowsCacheEntry)m_rowsCache.get(i);
            try {
                getRows(entry);
            }
            catch (Exception e) {
                System.err.println("WARNING: error in refreshing view cache for view "
                    + entry.getView());
            }
        }
    }

    private Iterator getRows(RowsCacheEntry entry) throws SQLException {
        return getRows(entry.getView(), entry.getSelects(), entry.getKeys(), entry.getValues(),
            new String[0]);
    }

    public void fetch(String packageName, MethodFilter sigf) throws SQLException {
        if (m_viewCacheDebug) {
            System.out.println("viewcache.fetch: " + packageName);
        }

        packageName = dbifyName(packageName);
        if (PARAMETER_ALL.equalsIgnoreCase(packageName)
            || PARAMETER_USER.equalsIgnoreCase(packageName)) {
            getRows(ALL_ARGUMENTS, new String[0], new String[]{}, new Object[]{}, new String[0]);
        }
        else {
            String[] keys = null;
            Object[] values = null;
            if (sigf != null && sigf.isSingleMethod()) {
                keys = new String[]{Util.PACKAGE_NAME, Util.OBJECT_NAME};
                values = new Object[]{packageName, sigf.getSingleMethodName()};
            }
            else {
                keys = new String[]{Util.PACKAGE_NAME};
                values = new Object[]{packageName};
            }
            getRows(ALL_ARGUMENTS, new String[0], keys, values, new String[0]);
        }
    }

    public int getHits() {
        return m_hits;
    }

    public int getVisits() {
        return m_visits;
    }

    public void reset(Connection conn) {
        m_conn = conn;
    }

    public void close() {
        try {
            if (m_conn != null) {
                m_conn.close();
            }
        }
        catch (Exception e) {
            // Closing resources. OK to ignore exception.
        }
    }

    public String getUser() {
        return m_user;
    }

    public String getFileName(String dir) {
        return getFileName(dir, m_user);
    }

    public static String getFileName(String dir, String user) {
        return (dir == null ? "" : dir + File.separator) + VIEW_CACHE_PREFIX + user.toLowerCase();
    }

    public void readExternal(java.io.ObjectInput in) throws IOException, ClassNotFoundException {
        if (m_viewCacheDebug) {
            System.out.println("viewcache.read.external");
        }
        // summary
        m_user = (String)in.readObject();
        m_hits = ((Integer)in.readObject()).intValue();
        m_visits = ((Integer)in.readObject()).intValue();

        // m_rowsCache
        int rowsCacheSize = ((Integer)in.readObject()).intValue();
        m_rowsCache = new ArrayList(rowsCacheSize);
        for (int i = 0; i < rowsCacheSize; i++) {
            RowsCacheEntry rce = (RowsCacheEntry)in.readObject();
            m_rowsCache.add(rce);
        }

        // m_rowsCacheIndex (String, ArrayList<ViewRow>)
        int rowsCacheIndexSize = ((Integer)in.readObject()).intValue();
        m_rowsCacheIndex = new HashMap(rowsCacheIndexSize);
        for (int i = 0; i < rowsCacheIndexSize; i++) {
            String key = (String)in.readObject();
            int rowsSize = ((Integer)in.readObject()).intValue();
            ArrayList rows = new ArrayList(rowsSize);
            for (int j = 0; j < rowsSize; j++) {
                ViewRow row = (ViewRow)in.readObject();
                rows.add(row);
            }
            m_rowsCacheIndex.put(key, rows);
        }
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        if (m_viewCacheDebug) {
            System.out.println("viewcache.write.external");
        }
        // summary
        out.writeObject(m_user);
        out.writeObject(Integer.valueOf(m_hits));
        out.writeObject(Integer.valueOf(m_visits));

        // m_rowsCache
        out.writeObject(Integer.valueOf(m_rowsCache.size()));
        for (int i = 0; i < m_rowsCache.size(); i++) {
            RowsCacheEntry rce = (RowsCacheEntry)m_rowsCache.get(i);
            out.writeObject(rce);
        }

        // m_rowsCacheIndex (String, ArrayList<ViewRow>)
        out.writeObject(Integer.valueOf(m_rowsCacheIndex.size()));
        Iterator keys = m_rowsCacheIndex.keySet().iterator();
        Iterator values = m_rowsCacheIndex.values().iterator();
        while (keys.hasNext()) {
            out.writeObject(keys.next());
            ArrayList rows = (ArrayList)values.next();
            out.writeObject(Integer.valueOf(rows.size()));
            for (int i = 0; i < rows.size(); i++) {
                out.writeObject(rows.get(i));
            }
        }
    }

    public String printSummary() {
        // summary
        String text = "";
        text += "****" + getFileName(null) + "****" + "\n";
        text += "schema: " + m_user + "\n";
        text += "hits/visits: " + m_hits + "/" + m_visits + "\n";
        for (int i = 0; i < m_rowsCache.size(); i++) {
            RowsCacheEntry rce = (RowsCacheEntry)m_rowsCache.get(i);
            text += rce.printSummary();
        }
        return text;
    }

    /*
     * if the name is quoted, the quotes are removed.
     *
     * public static String dbifyName(String s, SqlReflector reflector) { if (s == null ||
     * s.equals("") || reflector == null || reflector.getConnection() == null) { return s; } return
     * dbifyName(s, reflector.getViewCache()); }
     */

    public String dbifyName(String s) {
        if (s == null) {
            return "";
        }
        else if (s.equals("")) {
            return "";
        }
        else if (SqlName.isQuoted(s)) {
            return s.substring(1, s.length() - 1);
        }
        String upper_s = s.toUpperCase();
        String dbName = "";
        try {
            Iterator rowIter = getRows(Util.DUAL, new String[]{"UPPER('" + s + "') AS UPPER_NAME"},
                new String[0], new Object[0], new String[0]);
            if (rowIter.hasNext()) {
                SingleColumnViewRow row = (SingleColumnViewRow)rowIter.next();
                dbName = row.getValue();
            }
            else {
                // not found in viewCache and no database connection
                dbName = upper_s;
            }
        }
        catch (Exception ex) {
            System.err.println(ex.getMessage());
            dbName = upper_s;
        }
        return dbName;
    }

}
