/*
 * Copyright 2007 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.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * Validates the asynchronous version of
 * {@link com.google.gwt.user.client.rpc.RemoteService RemoteService} interface.
 */
class RemoteServiceAsyncValidator {
  static void logValidAsyncInterfaceDeclaration(TreeLogger logger,
      JClassType remoteService) {
    TreeLogger branch = logger.branch(TreeLogger.INFO,
        "A valid definition for the asynchronous version of interface '"
            + remoteService.getQualifiedSourceName() + "' would be:\n", null);
    branch.log(TreeLogger.ERROR,
        synthesizeAsynchronousInterfaceDefinition(remoteService), null);
  }

  private static String computeAsyncMethodSignature(JMethod syncMethod,
      JClassType asyncCallbackClass) {
    return computeInternalSignature(syncMethod) + "/"
        + asyncCallbackClass.getQualifiedSourceName();
  }

  private static String computeInternalSignature(JMethod method) {
    StringBuffer sb = new StringBuffer();
    sb.setLength(0);
    sb.append(method.getName());
    JParameter[] params = method.getParameters();
    for (JParameter param : params) {
      sb.append("/");
      JType paramType = param.getType();
      sb.append(paramType.getErasedType().getQualifiedSourceName());
    }
    return sb.toString();
  }

  /**
   * Builds a map of asynchronous method internal signatures to the
   * corresponding asynchronous {@link JMethod}.
   */
  private static Map<String, JMethod> initializeAsyncMethodMap(
      JMethod[] asyncMethods) {
    Map<String, JMethod> sigs = new TreeMap<String, JMethod>();
    for (JMethod asyncMethod : asyncMethods) {
      sigs.put(computeInternalSignature(asyncMethod), asyncMethod);
    }
    return sigs;
  }

  private static String synthesizeAsynchronousInterfaceDefinition(
      JClassType serviceIntf) {
    StringBuffer sb = new StringBuffer();
    JPackage pkg = serviceIntf.getPackage();
    if (pkg != null) {
      sb.append("\npackage ");
      sb.append(pkg.getName());
      sb.append(";\n");
    }

    sb.append("\npublic interface ");
    sb.append(serviceIntf.getSimpleSourceName());
    sb.append("Async {\n");

    JMethod[] methods = serviceIntf.getOverridableMethods();
    for (JMethod method : methods) {
      assert (method != null);

      sb.append("\tvoid ");
      sb.append(method.getName());
      sb.append("(");

      JParameter[] params = method.getParameters();
      for (int paramIndex = 0; paramIndex < params.length; ++paramIndex) {
        JParameter param = params[paramIndex];

        if (paramIndex > 0) {
          sb.append(", ");
        }

        sb.append(param.toString());
      }

      if (params.length > 0) {
        sb.append(", ");
      }

      JType returnType = method.getReturnType();
      sb.append(AsyncCallback.class.getName());
      sb.append("<");
      if (returnType instanceof JPrimitiveType) {
        sb.append(((JPrimitiveType) returnType).getQualifiedBoxedSourceName());
      } else {
        sb.append(returnType.getParameterizedQualifiedSourceName());
      }
      sb.append("> arg");
      sb.append(Integer.toString(params.length + 1));
      sb.append(");\n");
    }

    sb.append("}");

    return sb.toString();
  }

  private static void validationFailed(TreeLogger branch,
      JClassType remoteService) throws UnableToCompleteException {
    logValidAsyncInterfaceDeclaration(branch, remoteService);
    throw new UnableToCompleteException();
  }

  /**
   * {@link JClassType} for the {@link AsyncCallback} interface.
   */
  private final JClassType asyncCallbackClass;

  /**
   * {@link JClassType} for the {@link RequestBuilder} class.
   */
  private final JClassType requestBuilderType;

  /**
   * {@link JClassType} for the {@link Request} class.
   */
  private final JClassType requestType;

  RemoteServiceAsyncValidator(TreeLogger logger, TypeOracle typeOracle)
      throws UnableToCompleteException {
    try {
      asyncCallbackClass = typeOracle.getType(AsyncCallback.class.getName());
      requestType = typeOracle.getType(Request.class.getCanonicalName());
      requestBuilderType = typeOracle.getType(RequestBuilder.class.getCanonicalName());
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, null, e);
      throw new UnableToCompleteException();
    }
  }

  /**
   * Checks that for every method on the synchronous remote service interface
   * there is a corresponding asynchronous version in the asynchronous version
   * of the remote service. If the validation succeeds, a map of synchronous to
   * asynchronous methods is returned.
   * 
   * @param logger
   * @param remoteService
   * @return map of synchronous method to asynchronous method
   * 
   * @throws UnableToCompleteException if the asynchronous
   *           {@link com.google.gwt.user.client.rpc.RemoteService RemoteService}
   *           was not found, or if it does not have an asynchronous method
   *           version of every synchronous one
   */
  public Map<JMethod, JMethod> validate(TreeLogger logger,
      JClassType remoteService, JClassType remoteServiceAsync)
      throws UnableToCompleteException {
    TreeLogger branch = logger.branch(TreeLogger.DEBUG,
        "Checking the synchronous interface '"
            + remoteService.getQualifiedSourceName()
            + "' against its asynchronous version '"
            + remoteServiceAsync.getQualifiedSourceName() + "'", null);

    // Sync and async versions must have the same number of methods
    JMethod[] asyncMethods = remoteServiceAsync.getOverridableMethods();
    JMethod[] syncMethods = remoteService.getOverridableMethods();
    if (asyncMethods.length != syncMethods.length) {
      branch.branch(TreeLogger.ERROR, "The asynchronous version of "
          + remoteService.getQualifiedSourceName() + " has "
          + (asyncMethods.length > syncMethods.length ? "more" : "less")
          + " methods than the synchronous version", null);
      validationFailed(branch, remoteService);
    }

    // Check that for every sync method there is a corresponding async method
    boolean failed = false;
    Map<String, JMethod> asyncMethodMap = initializeAsyncMethodMap(asyncMethods);
    Map<JMethod, JMethod> syncMethodToAsyncMethodMap = new HashMap<JMethod, JMethod>();
    for (JMethod syncMethod : syncMethods) {
      String asyncSig = computeAsyncMethodSignature(syncMethod,
          asyncCallbackClass);
      JMethod asyncMethod = asyncMethodMap.get(asyncSig);
      if (asyncMethod == null) {
        branch.branch(TreeLogger.ERROR,
            "Missing asynchronous version of the synchronous method '"
                + syncMethod.getReadableDeclaration() + "'", null);
        failed = true;
      } else {
        // TODO if async param is parameterized make sure that the sync return
        // type is assignable to the first type argument
        JType returnType = asyncMethod.getReturnType();
        if (returnType != JPrimitiveType.VOID && returnType != requestType
            && returnType != requestBuilderType) {
          branch.branch(TreeLogger.ERROR,
              "The asynchronous version of the synchronous method '"
                  + syncMethod.getReadableDeclaration()
                  + "' must have a return type of 'void' or '"
                  + Request.class.getCanonicalName() + "' or '"
                  + RequestBuilder.class.getCanonicalName() + "'", null);
          failed = true;
        } else {
          syncMethodToAsyncMethodMap.put(syncMethod, asyncMethod);
        }
      }
    }

    if (failed) {
      validationFailed(branch, remoteService);
    }

    branch.log(TreeLogger.DEBUG, "Interfaces are in sync");

    return syncMethodToAsyncMethodMap;
  }
}
