// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor.sharepoint;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.logging.*;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.xml.ws.Holder;

/**
 * InvocationHandler that can wrap WebService instances and log input/output
 * values. This is more helpful than manual logging because it checks the
 * mode of a parameter and only prints it when appropriate. The mode of a
 * parameter defines when it is sent, so this logging method accurately
 * represents the exchange of information.
 */
class LoggingWSHandler implements InvocationHandler {
  private static final Logger log
      = Logger.getLogger(LoggingWSHandler.class.getName());

  private final Object wrapped;

  public LoggingWSHandler(Object wrapped) {
    this.wrapped = wrapped;
  }

  public static <T> T create(Class<T> webServiceInterface, T wrapped) {
    InvocationHandler invokeHandler = new LoggingWSHandler(wrapped);
    Object oInstance = Proxy.newProxyInstance(
        LoggingWSHandler.class.getClassLoader(),
        new Class<?>[] {webServiceInterface}, invokeHandler);
    @SuppressWarnings("unchecked")
    T tInstance = (T) oInstance;
    return tInstance;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    final Level logLevel = Level.FINE;
    if (log.isLoggable(logLevel)) {
      WebMethod webMethod = method.getAnnotation(WebMethod.class);
      if (webMethod != null) {
        String inArgs = formArgumentString(method, args, WebParam.Mode.IN);
        log.log(logLevel, "WS Request {0}: {1}",
            new Object[] {webMethod.operationName(), inArgs});
      }
    }
    Object ret;
    try {
      ret = method.invoke(wrapped, args);
    } catch (IllegalAccessException ex) {
      throw new RuntimeException("Misconfigured LoggingWSHandler", ex);
    } catch (IllegalArgumentException ex) {
      throw new RuntimeException("Misconfigured LoggingWSHandler", ex);
    } catch (InvocationTargetException ex) {
      throw ex.getCause();
    }
    if (log.isLoggable(logLevel)) {
      WebMethod webMethod = method.getAnnotation(WebMethod.class);
      if (webMethod != null) {
        String outArgs = formArgumentString(method, args, WebParam.Mode.OUT);
        log.log(logLevel, "WS Response {0}: {1}",
            new Object[] {webMethod.operationName(), outArgs});
      }
    }
    return ret;
  }

  private String formArgumentString(Method method, Object[] args,
      WebParam.Mode mode) {
    StringBuilder argsBuffer = new StringBuilder();
    Annotation[][] annotates = method.getParameterAnnotations();
    if (annotates.length != 0 && annotates.length != args.length) {
      throw new AssertionError();
    }
    for (int i = 0; i < annotates.length; i++) {
      for (Annotation annotate : annotates[i]) {
        if (!(annotate instanceof WebParam)) {
          break;
        }
        WebParam webParam = (WebParam) annotate;
        if (webParam.mode() == mode
            || webParam.mode() == WebParam.Mode.INOUT) {
          argsBuffer.append(", ").append(webParam.name()).append("=");
          if (webParam.mode() == WebParam.Mode.IN) {
            argsBuffer.append("" + args[i]);
          } else {
            Holder<?> holder = (Holder<?>) args[i];
            argsBuffer.append(
                holder == null ? "<null holder>" : "" + holder.value);
          }
        }
      }
    }
    return argsBuffer.length() > 1 ? argsBuffer.substring(2) : "";
  }
}
