/**
 * Copyright (C) 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.inject.persist.jpa;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.common.collect.MapMaker;
import com.google.inject.name.Named;
import com.google.inject.persist.finder.Finder;
import com.google.inject.persist.finder.FirstResult;
import com.google.inject.persist.finder.MaxResults;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * TODO(user): Make this work!!
 *
 * @author Dhanji R. Prasanna (dhanji@gmail.com)
 */
@Singleton
class JpaFinderProxy implements MethodInterceptor {
  private final Map<Method, FinderDescriptor> finderCache = new MapMaker().weakKeys().makeMap();
  private final Provider<EntityManager> emProvider;

  @Inject
  public JpaFinderProxy(Provider<EntityManager> emProvider) {
    this.emProvider = emProvider;
  }

  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    EntityManager em = emProvider.get();

    //obtain a cached finder descriptor (or create a new one)
    JpaFinderProxy.FinderDescriptor finderDescriptor = getFinderDescriptor(methodInvocation);

    Object result = null;

    //execute as query (named params or otherwise)
    Query jpaQuery = finderDescriptor.createQuery(em);
    if (finderDescriptor.isBindAsRawParameters) {
      bindQueryRawParameters(jpaQuery, finderDescriptor, methodInvocation.getArguments());
    } else {
      bindQueryNamedParameters(jpaQuery, finderDescriptor, methodInvocation.getArguments());
    }

    //depending upon return type, decorate or return the result as is
    if (JpaFinderProxy.ReturnType.PLAIN.equals(finderDescriptor.returnType)) {
      result = jpaQuery.getSingleResult();
    } else if (JpaFinderProxy.ReturnType.COLLECTION.equals(finderDescriptor.returnType)) {
      result = getAsCollection(finderDescriptor, jpaQuery.getResultList());
    } else if (JpaFinderProxy.ReturnType.ARRAY.equals(finderDescriptor.returnType)) {
      result = jpaQuery.getResultList().toArray();
    }

    return result;
  }

  private Object getAsCollection(JpaFinderProxy.FinderDescriptor finderDescriptor,
      List results) {
    Collection<?> collection;
    try {
      collection = (Collection) finderDescriptor.returnCollectionTypeConstructor.newInstance();
    } catch (InstantiationException e) {
      throw new RuntimeException(
          "Specified collection class of Finder's returnAs could not be instantated: "
              + finderDescriptor.returnCollectionType, e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(
          "Specified collection class of Finder's returnAs could not be instantated (do not have access privileges): "
              + finderDescriptor.returnCollectionType, e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(
          "Specified collection class of Finder's returnAs could not be instantated (it threw an exception): "
              + finderDescriptor.returnCollectionType, e);
    }

    collection.addAll(results);
    return collection;
  }

  private void bindQueryNamedParameters(Query jpaQuery,
      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
    for (int i = 0; i < arguments.length; i++) {
      Object argument = arguments[i];
      Object annotation = descriptor.parameterAnnotations[i];

      if (null == annotation)
      //noinspection UnnecessaryContinue
      {
        continue;   //skip param as it's not bindable
      } else if (annotation instanceof Named) {
        Named named = (Named) annotation;
        jpaQuery.setParameter(named.value(), argument);
      } else if (annotation instanceof javax.inject.Named) {
        javax.inject.Named named = (javax.inject.Named) annotation;
        jpaQuery.setParameter(named.value(), argument);
      } else if (annotation instanceof FirstResult) {
        jpaQuery.setFirstResult((Integer) argument);
      } else if (annotation instanceof MaxResults) {
        jpaQuery.setMaxResults((Integer) argument);
      }
    }
  }

  private void bindQueryRawParameters(Query jpaQuery,
      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {
    for (int i = 0, index = 1; i < arguments.length; i++) {
      Object argument = arguments[i];
      Object annotation = descriptor.parameterAnnotations[i];

      if (null == annotation) {
        //bind it as a raw param (1-based index, yes I know its different from Hibernate, blargh)
        jpaQuery.setParameter(index, argument);
        index++;
      } else if (annotation instanceof FirstResult) {
        jpaQuery.setFirstResult((Integer) argument);
      } else if (annotation instanceof MaxResults) {
        jpaQuery.setMaxResults((Integer) argument);
      }
    }
  }

  private JpaFinderProxy.FinderDescriptor getFinderDescriptor(MethodInvocation invocation) {
    Method method = invocation.getMethod();
    JpaFinderProxy.FinderDescriptor finderDescriptor = finderCache.get(method);
    if (null != finderDescriptor) {
      return finderDescriptor;
    }

    //otherwise reflect and cache finder info...
    finderDescriptor = new JpaFinderProxy.FinderDescriptor();

    //determine return type
    finderDescriptor.returnClass = invocation.getMethod().getReturnType();
    finderDescriptor.returnType = determineReturnType(finderDescriptor.returnClass);

    //determine finder query characteristics
    Finder finder = invocation.getMethod().getAnnotation(Finder.class);
    String query = finder.query();
    if (!"".equals(query.trim())) {
      finderDescriptor.setQuery(query);
    } else {
      finderDescriptor.setNamedQuery(finder.namedQuery());
    }

    //determine parameter annotations
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    Object[] discoveredAnnotations = new Object[parameterAnnotations.length];
    for (int i = 0; i < parameterAnnotations.length; i++) {
      Annotation[] annotations = parameterAnnotations[i];
      //each annotation per param
      for (Annotation annotation : annotations) {
        //discover the named, first or max annotations then break out
        Class<? extends Annotation> annotationType = annotation.annotationType();
        if (Named.class.equals(annotationType) || javax.inject.Named.class.equals(annotationType)) {
          discoveredAnnotations[i] = annotation;
          finderDescriptor.isBindAsRawParameters = false;
          break;
        } else if (FirstResult.class.equals(annotationType)) {
          discoveredAnnotations[i] = annotation;
          break;
        } else if (MaxResults.class.equals(annotationType)) {
          discoveredAnnotations[i] = annotation;
          break;
        }   //leave as null for no binding
      }
    }

    //set the discovered set to our finder cache object
    finderDescriptor.parameterAnnotations = discoveredAnnotations;

    //discover the returned collection implementation if this finder returns a collection
    if (JpaFinderProxy.ReturnType.COLLECTION.equals(finderDescriptor.returnType)
        && finderDescriptor.returnClass != Collection.class) {
      finderDescriptor.returnCollectionType = finder.returnAs();
      try {
        finderDescriptor.returnCollectionTypeConstructor = finderDescriptor.returnCollectionType
            .getConstructor();
        finderDescriptor.returnCollectionTypeConstructor.setAccessible(true);   //UGH!
      } catch (NoSuchMethodException e) {
        throw new RuntimeException(
            "Finder's collection return type specified has no default constructor! returnAs: "
                + finderDescriptor.returnCollectionType, e);
      }
    }

    //cache it
    cacheFinderDescriptor(method, finderDescriptor);

    return finderDescriptor;
  }

  /**
   * writes to a chm (used to provide copy-on-write but this is bettah!)
   *
   * @param method The key
   * @param finderDescriptor The descriptor to cache
   */
  private void cacheFinderDescriptor(Method method, FinderDescriptor finderDescriptor) {
    //write to concurrent map
    finderCache.put(method, finderDescriptor);
  }

  private JpaFinderProxy.ReturnType determineReturnType(Class<?> returnClass) {
    if (Collection.class.isAssignableFrom(returnClass)) {
      return JpaFinderProxy.ReturnType.COLLECTION;
    } else if (returnClass.isArray()) {
      return JpaFinderProxy.ReturnType.ARRAY;
    }

    return JpaFinderProxy.ReturnType.PLAIN;
  }

  /**
   * A wrapper data class that caches information about a finder method.
   */
  private static class FinderDescriptor {
    private volatile boolean isKeyedQuery = false;
    volatile boolean isBindAsRawParameters = true;
        //should we treat the query as having ? instead of :named params
    volatile JpaFinderProxy.ReturnType returnType;
    volatile Class<?> returnClass;
    volatile Class<? extends Collection> returnCollectionType;
    volatile Constructor returnCollectionTypeConstructor;
    volatile Object[] parameterAnnotations;
        //contract is: null = no bind, @Named = param, @FirstResult/@MaxResults for paging

    private String query;
    private String name;

    void setQuery(String query) {
      this.query = query;
    }

    void setNamedQuery(String name) {
      this.name = name;
      isKeyedQuery = true;
    }

    public boolean isKeyedQuery() {
      return isKeyedQuery;
    }

    Query createQuery(EntityManager em) {
      return isKeyedQuery ? em.createNamedQuery(name) : em.createQuery(query);
    }
  }

  private static enum ReturnType {
    PLAIN, COLLECTION, ARRAY
  }
}
