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

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.impl.ArtificialRescue;
import com.google.gwt.core.client.impl.Impl;
import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JArrayType;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JEnumType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.TypeOracleMediator;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.rpc.client.impl.CommandToStringWriter;
import com.google.gwt.rpc.client.impl.RpcServiceProxy;
import com.google.gwt.rpc.client.impl.TypeOverrides;
import com.google.gwt.rpc.linker.RpcDataArtifact;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.user.rebind.rpc.CustomFieldSerializerValidator;
import com.google.gwt.user.rebind.rpc.ProxyCreator;
import com.google.gwt.user.rebind.rpc.SerializableTypeOracle;
import com.google.gwt.user.rebind.rpc.SerializableTypeOracleBuilder;
import com.google.gwt.user.rebind.rpc.SerializationUtils;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Generates async proxy implementations using the RPC system.
 */
public class RpcProxyCreator extends ProxyCreator {
  private String typeOverrideName;

  public RpcProxyCreator(JClassType type) {
    super(type);
  }

  @Override
  protected String computeTypeNameExpression(JType paramType) {
    if (paramType.isClass() != null) {
      return "GWT.isScript() ? Impl.getNameOf(\"@"
          + paramType.getQualifiedSourceName() + "\") : \""
          + TypeOracleMediator.computeBinaryClassName(paramType) + "\"";
    } else {
      /*
       * Consider the case of service methods that have interface parameters;
       * these types don't necessarily exist in the client code, so we want to
       * encode these type names in a way that can always be distinguished from
       * obfuscated type names.
       */
      return "\" " + TypeOracleMediator.computeBinaryClassName(paramType)
          + "\"";
    }
  }

  @Override
  protected void generateProxyContructor(SourceWriter srcWriter) {
    srcWriter.println("public " + getProxySimpleName() + "() {");
    srcWriter.indent();
    srcWriter.println("super(GWT.getModuleBaseURL(),");
    srcWriter.indent();
    srcWriter.println(getRemoteServiceRelativePath() + ",");
    srcWriter.println("OVERRIDES);");
    srcWriter.outdent();
    srcWriter.outdent();
    srcWriter.println("}");
  }

  /**
   * Generate any fields required by the proxy.
   */
  @Override
  protected void generateProxyFields(SourceWriter srcWriter,
      SerializableTypeOracle serializableTypeOracle,
      String serializationPolicyStrongName, String remoteServiceInterfaceName) {
    // Initialize a field with binary name of the remote service interface
    srcWriter.println("private static final String REMOTE_SERVICE_INTERFACE_NAME = "
        + "\"" + remoteServiceInterfaceName + "\";");
    srcWriter.println("private static final " + TypeOverrides.class.getName()
        + " OVERRIDES = GWT.isScript() ? " + typeOverrideName
        + ".create() : null;");
    srcWriter.println();
  }

  @Override
  protected void generateStreamWriterOverride(SourceWriter srcWriter) {
    // Intentional no-op. Called if elideTypeNames is on, which is ignored
  }

  @Override
  protected void generateTypeHandlers(TreeLogger logger, GeneratorContext ctx,
      SerializableTypeOracle serializationSto,
      SerializableTypeOracle deserializationSto)
      throws UnableToCompleteException {
    String simpleName = serviceIntf.getSimpleSourceName()
        + "_TypeOverridesFactory";
    PrintWriter out = ctx.tryCreate(logger, serviceIntf.getPackage().getName(),
        simpleName);
    if (out == null) {
      return;
    }

    TypeOracle typeOracle = ctx.getTypeOracle();
    JClassType objectType = typeOracle.getJavaLangObject();
    Set<JType> classLiterals = new HashSet<JType>();
    Map<JType, JMethod> serializerMethods = new HashMap<JType, JMethod>();
    Map<JType, List<String>> fields = new HashMap<JType, List<String>>();

    StringBuilder sb = writeArtificialRescues(typeOracle, serializationSto,
        deserializationSto);

    ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(
        serviceIntf.getPackage().getName(), simpleName);
    composerFactory.addImport(ArtificialRescue.class.getCanonicalName());
    composerFactory.addImport(GWT.class.getCanonicalName());
    composerFactory.addImport(Impl.class.getCanonicalName());
    composerFactory.addImport(Rescue.class.getCanonicalName());
    composerFactory.addImport(TypeOverrides.class.getCanonicalName());
    composerFactory.addImport(TypeOverrides.SerializeFunction.class.getCanonicalName());

    composerFactory.addAnnotationDeclaration(sb.toString());
    SourceWriter sw = composerFactory.createSourceWriter(ctx, out);

    sw.println("public static TypeOverrides create() {");
    sw.indent();
    sw.println("TypeOverrides toReturn = TypeOverrides.create();");
    for (JType type : serializationSto.getSerializableTypes()) {
      JClassType classType = type.isClass();
      if (classType == null) {
        continue;
      }

      /*
       * Figure out which fields should be serialized and if there's a CFS. This
       * is done by crawling the supertype chain until we hit Object or a type
       * with a CFS.
       */
      boolean allFieldsAreSerializable = true;
      List<String> fieldRefs = new ArrayList<String>();
      JMethod serializerMethod = null;
      do {
        JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
            typeOracle, classType);
        serializerMethod = customSerializer == null ? null
            : CustomFieldSerializerValidator.getSerializationMethod(
                customSerializer, type.isClass());

        if (serializerMethod != null) {
          // Don't include any fields in the type
          break;
        }

        JField[] serializableFields = SerializationUtils.getSerializableFields(
            typeOracle, classType);
        allFieldsAreSerializable &= serializableFields.length == classType.getFields().length;
        for (JField field : serializableFields) {
          fieldRefs.add("@" + field.getEnclosingType().getQualifiedSourceName()
              + "::" + field.getName());
        }
        classType = classType.getSuperclass();
      } while (classType != objectType);

      if (allFieldsAreSerializable && serializerMethod == null) {
        // We can just inspect the object at runtime; best for code size
        continue;
      }

      if (serializerMethod != null || !fieldRefs.isEmpty()) {
        classLiterals.add(type);

        /*
         * toReturn.set(class_foo_Bar().getName(), serializer_foo_Bar(),
         * fields_foo_Bar());
         */
        String mangledTypeName = type.getQualifiedSourceName().replace('.', '_');
        sw.println("toReturn.set(class_" + mangledTypeName + "().getName()");
        if (serializerMethod == null) {
        } else {
          serializerMethods.put(type, serializerMethod);
          sw.indentln(",serializer_" + mangledTypeName + "()");
        }
        if (fieldRefs.isEmpty()) {
          sw.indentln(");");
        } else {
          fields.put(type, fieldRefs);
          sw.indentln(",fields_" + mangledTypeName + "());");
        }
      }
    }

    sw.println("return toReturn;");
    sw.outdent();
    sw.println("}");

    for (JType classLiteral : classLiterals) {
      sw.println("public static native Class class_"
          + classLiteral.getQualifiedSourceName().replace('.', '_') + "() /*-{");
      sw.indentln("return @" + classLiteral.getQualifiedSourceName()
          + "::class;");
      sw.println("}-*/;");
      sw.println();
    }

    for (Map.Entry<JType, JMethod> entry : serializerMethods.entrySet()) {
      sw.println("public static native "
          + TypeOverrides.SerializeFunction.class.getSimpleName()
          + " serializer_"
          + entry.getKey().getQualifiedSourceName().replace('.', '_')
          + "() /*-{");
      sw.indentln("return " + entry.getValue().getJsniSignature() + ";");
      sw.println("}-*/;");
      sw.println();
    }

    for (Map.Entry<JType, List<String>> entry : fields.entrySet()) {
      sw.println("public static String[] fields_"
          + entry.getKey().getQualifiedSourceName().replace('.', '_') + "() {");
      sw.print("return new String[] {");
      for (String fieldRef : entry.getValue()) {
        sw.print("Impl.getNameOf(\"" + fieldRef + "\"),");
      }
      sw.println("};");
      sw.println("}");
      sw.println();
    }

    sw.commit(logger);

    typeOverrideName = composerFactory.getCreatedClassName();
  }

  @Override
  protected Class<? extends RemoteServiceProxy> getProxySupertype() {
    return RpcServiceProxy.class;
  }

  @Override
  protected Class<? extends SerializationStreamWriter> getStreamWriterClass() {
    return CommandToStringWriter.class;
  }

  @Override
  protected String writeSerializationPolicyFile(TreeLogger logger,
      GeneratorContext ctx, SerializableTypeOracle serializationSto,
      SerializableTypeOracle deserializationSto)
      throws UnableToCompleteException {

    RpcDataArtifact data = new RpcDataArtifact(
        serviceIntf.getQualifiedSourceName());

    for (JType type : deserializationSto.getSerializableTypes()) {
      if (!(type instanceof JClassType)) {
        continue;
      }

      JField[] serializableFields = SerializationUtils.getSerializableFields(
          ctx.getTypeOracle(), (JClassType) type);

      List<String> names = Lists.create();
      for (int i = 0, j = serializableFields.length; i < j; i++) {
        names = Lists.add(names, serializableFields[i].getName());
      }

      data.setFields(TypeOracleMediator.computeBinaryClassName(type), names);
    }

    ctx.commitArtifact(logger, data);

    return "unused";
  }

  private StringBuilder writeArtificialRescues(TypeOracle typeOracle,
      SerializableTypeOracle serializationSto,
      SerializableTypeOracle deserializationSto) {
    Set<JType> serializableTypes = new HashSet<JType>();
    Collections.addAll(serializableTypes,
        serializationSto.getSerializableTypes());
    Collections.addAll(serializableTypes,
        deserializationSto.getSerializableTypes());
    for (JMethod m : serviceIntf.getOverridableMethods()) {
      // Pick up any primitive return types, which get sent boxed
      JPrimitiveType mustBox = m.getReturnType().isPrimitive();
      if (mustBox != null) {
        serializableTypes.add(m.getReturnType());
      }
    }

    StringBuilder sb = new StringBuilder("@ArtificialRescue({");
    for (JType serializableType : serializableTypes) {

      JArrayType serializableArray = serializableType.isArray();
      JClassType serializableClass = serializableType.isClass();
      JPrimitiveType serializablePrimitive = serializableType.isPrimitive();
      if (serializableArray != null) {
        sb.append("\n@Rescue(className = \"");
        if (serializableArray.getLeafType() instanceof JPrimitiveType) {
          sb.append(serializableArray.getLeafType().getJNISignature());
          for (int i = 0, j = serializableArray.getRank(); i < j; i++) {
            sb.append("[]");
          }
        } else {
          sb.append(serializableArray.getQualifiedSourceName());
        }
        sb.append("\",\n instantiable = true),");

      } else if (serializableClass != null) {
        writeSingleRescue(typeOracle, deserializationSto, sb, serializableClass);

      } else if (serializablePrimitive != null) {
        JClassType boxedClass = typeOracle.findType(serializablePrimitive.getQualifiedBoxedSourceName());
        assert boxedClass != null : "No boxed version of "
            + serializablePrimitive.getQualifiedSourceName();
        writeSingleRescue(typeOracle, deserializationSto, sb, boxedClass);
      }
    }
    sb.append("})");
    return sb;
  }

  /**
   * Writes the rescue of a serializable type and its custom serialization
   * logic.
   */
  private void writeSingleRescue(TypeOracle typeOracle,
      SerializableTypeOracle deserializationOracle, StringBuilder sb,
      JClassType serializableClass) {
    boolean shouldDeserialize = deserializationOracle.isSerializable(serializableClass);

    // Pull the two custom serialization methods
    JClassType customSerializer;
    JMethod deserialize = null;
    JMethod instantiate = null;

    // An automatically-serializable subclass of a manually serialized class
    boolean hybridSerialization = false;

    {
      JClassType search = serializableClass;
      do {
        customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(
            typeOracle, search);

        if (customSerializer != null) {
          instantiate = CustomFieldSerializerValidator.getInstantiationMethod(
              customSerializer, search);

          deserialize = CustomFieldSerializerValidator.getDeserializationMethod(
              customSerializer, search);

          hybridSerialization = search != serializableClass;
          break;
        }

        search = search.getSuperclass();
      } while (search != null);
    }

    // The fields that should be preserved from being pruned
    JField[] serializableFields;
    JEnumType enumType = serializableClass.isEnum();
    if (enumType != null) {
      serializableFields = enumType.getFields();
    } else {
      serializableFields = SerializationUtils.getSerializableFields(typeOracle,
          serializableClass);
    }

    /*
     * We need to rescue the constructor if there is no instantiate method and
     * there is a custom deserialize method.
     */
    boolean rescueConstructor = instantiate == null && deserialize != null;

    /*
     * There may be either no custom serializer or a custom serializer that
     * doesn't define the instantiate method.
     */
    if (shouldDeserialize || rescueConstructor
        || (customSerializer == null && serializableFields.length > 0)) {

      /*
       * @Rescue(className="package.Foo$Inner", instantiable=true, fields={..},
       * methods={..}),
       */
      sb.append("\n@Rescue(className = \"").append(
          serializableClass.getQualifiedSourceName()).append("\"");

      sb.append(",\n instantiable = ").append(shouldDeserialize);
      sb.append(",\n fields = {");
      if (customSerializer == null || hybridSerialization) {
        for (JField field : serializableFields) {
          sb.append("\"").append(field.getName()).append("\",");
        }
      }
      sb.append("},\n methods = {");
      if (rescueConstructor) {
        sb.append("\"").append(serializableClass.getName().replace('.', '$')).append(
            "()\"");
      }
      sb.append("}),");
    }

    // Rescue the custom serialization logic if any exists
    if (customSerializer != null) {
      sb.append("\n@Rescue(className = \"").append(
          customSerializer.getQualifiedSourceName()).append("\",\n methods = {");
      if (instantiate != null) {
        String jsniSignature = instantiate.getJsniSignature();
        sb.append("\"").append(
            jsniSignature.substring(jsniSignature.lastIndexOf(':') + 1)).append(
            "\",");
      }
      if (deserialize != null) {
        String jsniSignature = deserialize.getJsniSignature();
        sb.append("\"").append(
            jsniSignature.substring(jsniSignature.lastIndexOf(':') + 1)).append(
            "\",");
      }
      sb.append("}),");
    }
  }
}
