/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ode.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.Statement;
import java.util.*;

import javax.sql.DataSource;

import org.slf4j.Logger;

public class LoggingInterceptor<T> implements InvocationHandler {

    private static final Set<String> PARAMSTYPES = new HashSet<String>();
    static {
        PARAMSTYPES.add("setArray");
        PARAMSTYPES.add("setBigDecimal");
        PARAMSTYPES.add("setBoolean");
        PARAMSTYPES.add("setByte");
        PARAMSTYPES.add("setBytes");
        PARAMSTYPES.add("setDate");
        PARAMSTYPES.add("setDouble");
        PARAMSTYPES.add("setFloat");
        PARAMSTYPES.add("setInt");
        PARAMSTYPES.add("setLong");
        PARAMSTYPES.add("setObject");
        PARAMSTYPES.add("setRef");
        PARAMSTYPES.add("setShort");
        PARAMSTYPES.add("setString");
        PARAMSTYPES.add("setTime");
        PARAMSTYPES.add("setTimestamp");
        PARAMSTYPES.add("setURL");
    }

    private Logger _log;
    private T _delegate;
    private Map<String, Object> _paramsByName = new TreeMap<String, Object>();
    private Map<Integer, Object> _paramsByIdx = new TreeMap<Integer, Object>();


    public LoggingInterceptor(T delegate, Logger log) {
        _log = log;
        _delegate = delegate;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        try {
            if (method.getDeclaringClass() == DataSource.class
                    && "getConnection".equals(method.getName())) {
                Connection conn = (Connection)method.invoke(_delegate, args);
                print("getConnection (tx=" + conn.getTransactionIsolation() + ")");
                return Proxy.newProxyInstance(_delegate.getClass().getClassLoader(),
                        new Class[] {Connection.class}, new LoggingInterceptor<Connection>(conn, _log));
            } else if (method.getDeclaringClass() == Connection.class
                    && Statement.class.isAssignableFrom(method.getReturnType())) {
                Statement stmt = (Statement)method.invoke(_delegate, args);
                print(method, args);
                return Proxy.newProxyInstance(_delegate.getClass().getClassLoader(),
                        new Class[] {method.getReturnType()}, new LoggingInterceptor<Statement>(stmt, _log));
            } else {
                print(method, args);
                return method.invoke(_delegate, args);
            }
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    private void print(Method method, Object[] args) {
        if (shouldPrint()) {
            // JDBC Connection
            if ("prepareStatement".equals(method.getName())) {
                print("prepareStatement: " + args[0]);
            } else if ("prepareCall".equals(method.getName())) {
                print("prepareCall: " + args[0]);
            } else if ("close".equals(method.getName())) {
                print("close()");
            } else if ("commit".equals(method.getName())) {
                print("commit()");
            } else if ("rollback".equals(method.getName())) {
                print("rollback()");
            } else if ("setTransactionIsolation".equals(method.getName())) {
                print("Set isolation level to " + args[0]);
            }
            // JDBC Statement
            else if (method.getName().startsWith("execute") && args != null && args.length == 1 && args[0] instanceof String) {
                print(method.getName() + "(" + args[0] + "), " + getParams());
            } else if (method.getName().startsWith("execute")) {
                print(method.getName() + ", " + getParams());
            } else if ("clearParameters".equals(method.getName())) {
                _paramsByIdx.clear();
                _paramsByName.clear();
            } else if ("setNull".equals(method.getName())) {
                if (String.class.isAssignableFrom(args[0].getClass())) {
                    _paramsByName.put((String)args[0], null);
                } else if (Integer.class.isAssignableFrom(args[0].getClass())) {
                    _paramsByIdx.put((Integer)args[0], null);
                }
            } else if (PARAMSTYPES.contains(method.getName())){
                if (String.class.isAssignableFrom(args[0].getClass())) {
                    _paramsByName.put((String)args[0], args[1]);
                } else if (Integer.class.isAssignableFrom(args[0].getClass())) {
                    _paramsByIdx.put((Integer)args[0], args[1]);
                }
            }
        }
    }

    private String getParams() {
        if (_paramsByIdx.size() > 0 || _paramsByName.size() > 0) {
            StringBuffer buf = new StringBuffer();
            buf.append("bound ");
            for (Map.Entry<Integer, Object> entry : _paramsByIdx.entrySet()) {
                try {
                    buf.append("(").append(entry.getKey()).append(",").append(entry.getValue()).append(") ");
                } catch (Throwable e) {
                    // We don't want to mess with the connection just for logging
                    return "[e]";
                }
            }
            for (Map.Entry<String, Object> entry : _paramsByName.entrySet()) {
                try {
                    buf.append("(").append(entry.getKey()).append(",").append(entry.getValue()).append(") ");
                } catch (Throwable e) {
                    // We don't want to mess with the connection just for logging
                    return "[e]";
                }
            }
            return buf.toString();
        }
        return "w/o params";
    }

    private boolean shouldPrint() {
        if (_log != null)
            return _log.isDebugEnabled();
        else return true;
    }

    private void print(String str) {
        if (_log != null)
            _log.debug(str);
        else System.out.println(str);
    }

    public static DataSource createLoggingDS(DataSource ds, Logger log) {
        return (DataSource)Proxy.newProxyInstance(ds.getClass().getClassLoader(),
                new Class[] {DataSource.class}, new LoggingInterceptor<DataSource>(ds,log));
    }
}
