/*
 * 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.user.rebind.rpc;

import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.ConfigurationProperty;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.SelectionProperty;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JArrayType;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;

import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

class Shared {

  /**
   * Property used to control whether or not the RPC system will emit warnings
   * when a type has final fields.
   */
  private static final String RPC_PROP_SUPPRESS_NON_STATIC_FINAL_FIELD_WARNINGS = "gwt.suppressNonStaticFinalFieldWarnings";

  /**
   * Multi-valued configuration property used to list classes that are
   * (potentially) enhanced with server-only fields, to be handled specially by
   * RPC.
   */
  private static final String RPC_ENHANCED_CLASSES = "rpc.enhancedClasses";

  /**
   * Capitalizes a name.
   * 
   * @param name the string to be capitalized
   * @return the capitalized string
   */
  static String capitalize(String name) {
    return name.substring(0, 1).toUpperCase(Locale.US) + name.substring(1);
  }
  
  /**
   * Returns a Set of names of classes that may be enhanced with extra server-only fields.
   * 
   * @param propertyOracle The propertyOracle used to access the relevant configuration
   * property.
   * @return a Set of Strings, or null.
   */
  static Set<String> getEnhancedTypes(PropertyOracle propertyOracle) {
    try {
      ConfigurationProperty prop = propertyOracle.getConfigurationProperty(RPC_ENHANCED_CLASSES);
      return Collections.unmodifiableSet(new HashSet<String>(prop.getValues()));
    } catch (BadPropertyValueException e) {
      return null;
    }
  }

  static String getStreamReadMethodNameFor(JType type) {
    return "read" + getCallSuffix(type);
  }

  static String getStreamWriteMethodNameFor(JType type) {
    return "write" + getCallSuffix(type);
  }

  /**
   * Returns <code>true</code> if warnings should not be emitted for final
   * fields in serializable types.
   */
  static boolean shouldSuppressNonStaticFinalFieldWarnings(TreeLogger logger,
      PropertyOracle propertyOracle) {
    return getBooleanProperty(logger, propertyOracle,
        RPC_PROP_SUPPRESS_NON_STATIC_FINAL_FIELD_WARNINGS, false);
  }

  /**
   * Computes a good name for a class related to the specified type, such that
   * the computed name can be a top-level class in the same package as the
   * specified type.
   * 
   * <p>
   * This method does not currently check for collisions between the synthesized
   * name and an existing top-level type in the same package. It is actually
   * tricky to do so, because on subsequent runs, we'll view our own generated
   * classes as collisions. There's probably some trick we can use in the future
   * to make it totally bulletproof.
   * </p>
   * 
   * @param type the name of the base type, whose name will be built upon to
   *          synthesize a new type name
   * @param suffix a suffix to be used to make the new synthesized type name
   * @return an array of length 2 such that the first element is the package
   *         name and the second element is the synthesized class name
   */
  static String[] synthesizeTopLevelClassName(JClassType type, String suffix) {
    // Gets the basic name of the type. If it's a nested type, the type name
    // will contains dots.
    //
    String className;
    String packageName;

    JType leafType = type.getLeafType();
    if (leafType.isPrimitive() != null) {
      className = leafType.getSimpleSourceName();
      packageName = "com.google.gwt.user.client.rpc.core";
    } else {
      JClassType classOrInterface = leafType.isClassOrInterface();
      assert (classOrInterface != null);
      className = classOrInterface.getName();
      packageName = classOrInterface.getPackage().getName();
    }

    JArrayType isArray = type.isArray();
    if (isArray != null) {
      className += "_Array_Rank_" + isArray.getRank();
    }

    // Add the meaningful suffix.
    //
    className += suffix;

    // Make it a top-level name.
    //
    className = className.replace('.', '_');

    return new String[] {packageName, className};
  }

  /**
   * Determines whether a particular type needs to be cast to become its final
   * type. Primitives and Strings do not, as they are read directly as the
   * correct type. All other Objects need a cast, except for Object itself.
   * 
   * @param type the type in question
   * @return <code>true</code> if the results of a read method must be cast,
   *         otherwise <code>false</code>.
   */
  static boolean typeNeedsCast(JType type) {
    return type.isPrimitive() == null
        && !type.getQualifiedSourceName().equals("java.lang.String")
        && !type.getQualifiedSourceName().equals("java.lang.Object");
  }

  private static boolean getBooleanProperty(TreeLogger logger,
      PropertyOracle propertyOracle, String propertyName, boolean defaultValue) {
    try {
      SelectionProperty prop
         = propertyOracle.getSelectionProperty(logger, propertyName);
      String propVal = prop.getCurrentValue();
      if (propVal != null && propVal.length() > 0) {
        return Boolean.valueOf(propVal);
      }
    } catch (BadPropertyValueException e) {
      // Just return the default value.
    }
    return defaultValue;
  }

  /**
   * Gets the suffix needed to make a call for a particular type. For example,
   * the <code>int</code> class needs methods named "readInt" and "writeInt".
   * 
   * @param type the type in question
   * @return the suffix of the method to call
   */
  private static String getCallSuffix(JType type) {
    JParameterizedType isParameterized = type.isParameterized();
    if (isParameterized != null) {
      return getCallSuffix(isParameterized.getRawType());
    } else if (type.isPrimitive() != null) {
      if (type == JPrimitiveType.BOOLEAN) {
        return "Boolean";
      } else if (type == JPrimitiveType.BYTE) {
        return "Byte";
      } else if (type == JPrimitiveType.CHAR) {
        return "Char";
      } else if (type == JPrimitiveType.DOUBLE) {
        return "Double";
      } else if (type == JPrimitiveType.FLOAT) {
        return "Float";
      } else if (type == JPrimitiveType.INT) {
        return "Int";
      } else if (type == JPrimitiveType.LONG) {
        return "Long";
      } else if (type == JPrimitiveType.SHORT) {
        return "Short";
      } else {
        return null;
      }
    } else if (type.getQualifiedSourceName().equals("java.lang.String")) {
      return "String";
    } else {
      return "Object";
    }
  }
}
