/*
 * Copyright 2010 Google Inc.
 * 
 * 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.gwt.requestfactory.server;

import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.InstanceRequest;
import com.google.gwt.requestfactory.shared.ProxyFor;
import com.google.gwt.requestfactory.shared.ProxyForName;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.Service;
import com.google.gwt.requestfactory.shared.ServiceName;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;

/**
 * OperationRegistry which uses the operation name as a convention for
 * reflection to a method on a class, and returns an appropriate
 * {@link com.google.gwt.requestfactory.server.RequestDefinition}.
 */
class ReflectionBasedOperationRegistry implements OperationRegistry {

  class ReflectiveRequestDefinition implements RequestDefinition {

    private Class<?> requestClass;

    private Method requestMethod;

    private Class<?> domainClass;

    private Method domainMethod;

    private boolean isInstance;

    public ReflectiveRequestDefinition(Class<?> requestClass,
        Method requestMethod, Class<?> domainClass, Method domainMethod,
        boolean isInstance) {
      this.requestClass = requestClass;
      this.requestMethod = requestMethod;
      this.domainClass = domainClass;
      this.domainMethod = domainMethod;
      this.isInstance = isInstance;
    }

    public String getDomainClassName() {
      return domainClass.getCanonicalName();
    }

    public Method getDomainMethod() {
      return domainMethod;
    }

    public String getDomainMethodName() {
      return getDomainMethod().getName();
    }

    public Class<?>[] getParameterTypes() {
      return domainMethod.getParameterTypes();
    }

    /**
     * Treat instance invocations as though they were static implementations.
     */
    public Type[] getRequestParameterTypes() {
      Type[] toReturn = requestMethod.getGenericParameterTypes();
      if (isInstance()) {
        // Instance method, add a "this" parameter at the beginning
        Type[] newReturn = new Type[toReturn.length + 1];
        newReturn[0] = domainMethod.getDeclaringClass();
        System.arraycopy(toReturn, 0, newReturn, 1, toReturn.length);
        toReturn = newReturn;
      }
      return toReturn;
    }

    public Class<?> getReturnType() {
      Class<?> domainReturnType = getReturnTypeFromParameter(domainMethod,
          domainMethod.getGenericReturnType());
      Class<?> requestReturnType = getReturnTypeFromParameter(requestMethod,
          requestMethod.getGenericReturnType());
      if (EntityProxy.class.isAssignableFrom(requestReturnType)) {
        ProxyFor annotation = requestReturnType.getAnnotation(ProxyFor.class);
        ProxyForName nameAnnotation = requestReturnType.getAnnotation(ProxyForName.class);

        Class<?> dtoClass = null;
        if (annotation != null) {
          dtoClass = annotation.value();
        } else if (nameAnnotation != null) {
          try {
            dtoClass = Class.forName(nameAnnotation.value(), false,
                Thread.currentThread().getContextClassLoader());
          } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException(
                "Unknown type specified in ProxyForName annotation", e);
          }
        } else {
          throw new IllegalArgumentException(
              "Missing ProxyFor annotation on proxy type " + requestReturnType);
        }
        if (!dtoClass.equals(domainReturnType)) {
          throw new IllegalArgumentException("Type mismatch between "
              + domainMethod + " return type, and " + requestReturnType
              + "'s ProxyFor annotation " + dtoClass);
        }
        return requestReturnType;
      }
      // primitive ?
      return requestReturnType;
    }

    public boolean isInstance() {
      return isInstance;
    }

    public String name() {
      return requestClass.getCanonicalName() + SCOPE_SEPARATOR
          + getDomainMethodName();
    }

    private Class<?> getReturnTypeFromParameter(Method method, Type type) {
      if (type instanceof ParameterizedType) {
        ParameterizedType pType = (ParameterizedType) type;
        Class<?> rawType = (Class<?>) pType.getRawType();
        if (List.class.isAssignableFrom(rawType)
            || Request.class.isAssignableFrom(rawType)
            || InstanceRequest.class.isAssignableFrom(rawType)) {
          Class<?> rType = getTypeArgument(pType);
          if (rType != null) {
            if (List.class.isAssignableFrom(rType)) {
              return getReturnTypeFromParameter(method, rType);
            }
            return rType;
          }
          throw new IllegalArgumentException(
              "Bad or missing type arguments for "
                  + "List return type on method " + method);
        } else if (Set.class.isAssignableFrom(rawType)
            || Request.class.isAssignableFrom(rawType)
            || InstanceRequest.class.isAssignableFrom(rawType)) {
          Class<?> rType = getTypeArgument(pType);
          if (rType != null) {
            if (Set.class.isAssignableFrom(rType)) {
              return getReturnTypeFromParameter(method, rType);
            }
            return rType;
          }
          throw new IllegalArgumentException(
              "Bad or missing type arguments for "
                  + "Set return type on method " + method);
        }
      } else {
        // Primitive?
        return (Class<?>) type;
      }
      return null;
    }

    @SuppressWarnings("unchecked")
    private Class<?> getTypeArgument(ParameterizedType type) {
      Type[] params = type.getActualTypeArguments();
      Type toExamine;
      if (params.length == 1) {
        toExamine = params[0];
      } else if (InstanceRequest.class.equals(type.getRawType())) {
        toExamine = params[1];
      } else {
        return null;
      }

      if (toExamine instanceof ParameterizedType) {
        // if type is for example, RequestObject<List<T>> we return T
        return getTypeArgument((ParameterizedType) toExamine);
      }
      // else, it might be a case like List<T> in which case we return T
      return (Class<Object>) toExamine;
    }
  }

  public static final String SCOPE_SEPARATOR = "::";

  private RequestSecurityProvider securityProvider;

  /**
   * Constructs a {@link ReflectionBasedOperationRegistry} instance with a given
   * {@link RequestSecurityProvider}.
   * 
   * @param securityProvider a {@link RequestSecurityProvider} instance.
   */
  public ReflectionBasedOperationRegistry(
      RequestSecurityProvider securityProvider) {
    this.securityProvider = securityProvider;
  }

  /**
   * Turns an operation in the form of package.requestClass::method into a
   * RequestDefinition via reflection.
   */
  public RequestDefinition getOperation(String operationName) {
    String decodedOperationName = securityProvider.mapOperation(operationName);
    String parts[] = decodedOperationName.split(SCOPE_SEPARATOR);
    final String reqClassName = parts[0];
    final String domainMethodName = parts[1];
    try {
      // Do not invoke static initializer before checking if this class can be
      // legally invoked
      Class<?> requestClass = Class.forName(reqClassName, false,
          this.getClass().getClassLoader());
      securityProvider.checkClass(requestClass);
      Service domainClassAnnotation = requestClass.getAnnotation(Service.class);
      ServiceName domainClassNameAnnotation = requestClass.getAnnotation(ServiceName.class);
      Class<?> domainClass;
      if (domainClassAnnotation != null) {
        domainClass = domainClassAnnotation.value();
      } else if (domainClassNameAnnotation != null) {
        domainClass = Class.forName(domainClassNameAnnotation.value(), false,
            Thread.currentThread().getContextClassLoader());
      } else {
        return null;
      }

      Method requestMethod = findMethod(requestClass, domainMethodName);
      Method domainMethod = findMethod(domainClass, domainMethodName);
      if (requestMethod != null && domainMethod != null) {
        boolean isInstance = InstanceRequest.class.isAssignableFrom(requestMethod.getReturnType());
        if (isInstance == Modifier.isStatic(domainMethod.getModifiers())) {
          throw new IllegalArgumentException("domain method " + domainMethod
              + " and interface method " + requestMethod
              + " don't match wrt instance/static");
        }
        return new ReflectiveRequestDefinition(requestClass, requestMethod,
            domainClass, domainMethod, isInstance);
      }

      return null;
    } catch (ClassNotFoundException e) {
      throw new SecurityException("Access to non-existent class "
          + reqClassName);
    }
  }

  public RequestSecurityProvider getSecurityProvider() {
    return securityProvider;
  }

  private Method findMethod(Class<?> clazz, String methodName) {
    for (Method method : clazz.getDeclaredMethods()) {
      if ((method.getModifiers() & Modifier.PUBLIC) != 0) {
        if (method.getName().equals(methodName)) {
          return method;
        }
      }
    }
    return null;
  }
}
