/*
 * Copyright 2008 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.core.ext.soyc.impl;

import com.google.gwt.core.ext.soyc.Member;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.js.ast.JsFunction;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.IdentityHashMap;
import java.util.Map;

/**
 * A factory object for the standard implementations of Member subtypes. The
 * factory methods in this type provide canonicalized instances. The maps used
 * by MemberFactory use hard, identity-based references.
 */
public class MemberFactory {
  private final Map<Class<?>, Map<?, ?>> map = new IdentityHashMap<Class<?>, Map<?, ?>>();

  public StandardFieldMember get(JField field) {
    return getOrCreate(field, StandardFieldMember.class, JField.class);
  }

  public StandardMethodMember get(JMethod method) {
    return getOrCreate(method, StandardMethodMember.class, JMethod.class);
  }

  public StandardClassMember get(JDeclaredType type) {
    return getOrCreate(type, StandardClassMember.class, JDeclaredType.class);
  }

  public StandardFunctionMember get(JsFunction function) {
    return getOrCreate(function, StandardFunctionMember.class, JsFunction.class);
  }

  @SuppressWarnings("unchecked")
  private <K, V extends Member> Map<K, V> getElementMap(Class<V> clazz) {
    Map<K, V> elementMap = (Map<K, V>) map.get(clazz);
    if (elementMap == null) {
      elementMap = new IdentityHashMap<K, V>();
      map.put(clazz, elementMap);
    }
    return elementMap;
  }

  /**
   * Assumes that the implementation of Member has a two-arg constructor that
   * accepts a MemberFactory and the key.
   * 
   * @param <K> the type of key used to canonicalize the mapping
   * @param <V> the type of Member implementation to use
   * @param key the key by which the value should be canonicalized
   * @param implClazz the concrete type of Member to construct
   * @param constructorParam the declared type of the second parameter of the
   *          concrete Member type
   * @return the canonicalized instance of Member for the given key
   */
  private <K, V extends Member> V getOrCreate(K key, Class<V> implClazz,
      Class<? super K> constructorParam) {
    Map<K, V> elementMap = getElementMap(implClazz);

    V toReturn = elementMap.get(key);
    if (toReturn == null) {
      try {
        Constructor<V> ctor = implClazz.getConstructor(MemberFactory.class,
            constructorParam);
        toReturn = ctor.newInstance(this, key);
      } catch (NoSuchMethodException e) {
        throw new RuntimeException(implClazz.getName()
            + " must declare a two-arg (MemberFactory, "
            + constructorParam.getName() + ") constructor", e);
      } catch (IllegalArgumentException e) {
        // Error on the part of this type
        throw new RuntimeException(e);
      } catch (InstantiationException e) {
        // Error on the part of this type, asking for a non-instantiable type
        throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
        // Error on the part of the coder of implClazz
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        // Probably a RuntimeException thrown from the constructor
        if (e.getCause() instanceof RuntimeException) {
          throw (RuntimeException) e.getCause();
        }
        throw new RuntimeException(e);
      }

      elementMap.put(key, toReturn);
    }

    return toReturn;
  }
}