/*
 * Copyright 2014 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.dev.jjs.impl;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;

/**
 * Checks and throws errors for invalid JSNI constructs.
 */
public class JsniRestrictionChecker extends JVisitor {

  public static void exec(TreeLogger logger, JProgram jprogram) throws UnableToCompleteException {
    JsniRestrictionChecker jsniRestrictionChecker = new JsniRestrictionChecker(logger, jprogram);
    jsniRestrictionChecker.accept(jprogram);
    if (jsniRestrictionChecker.hasErrors) {
      throw new UnableToCompleteException();
    }
  }

  private JMethod currentJsniMethod;
  private final JProgram jprogram;
  private final TreeLogger logger;
  private boolean hasErrors;

  public JsniRestrictionChecker(TreeLogger logger, JProgram jprogram) {
    this.logger = logger;
    this.jprogram = jprogram;
  }

  @Override
  public boolean visit(JsniMethodBody x, Context ctx) {
    currentJsniMethod = x.getMethod();
    return super.visit(x, ctx);
  }

  @Override
  public boolean visit(JsniMethodRef x, Context ctx) {
    JMethod calledMethod = x.getTarget();
    JDeclaredType enclosingTypeOfCalledMethod = calledMethod.getEnclosingType();

    if (isNonStaticJsoClassDispatch(calledMethod, enclosingTypeOfCalledMethod)) {
      logError("JSNI method %s  attempts to call non-static method %s on an instance which is a "
          + "subclass of JavaScriptObject. Only static method calls on JavaScriptObject subclasses "
          + "are allowed in JSNI.", currentJsniMethod.getQualifiedName(),
          calledMethod.getQualifiedName());
    } else if (isJsoInterface(enclosingTypeOfCalledMethod)) {
      logError("JSNI method %s attempts to call method %s on an instance which might be a "
          + "JavaScriptObject. Such a method call is only allowed in pure Java (non-JSNI) "
          + "functions.", currentJsniMethod.getQualifiedName(), calledMethod.getQualifiedName());
    } else if (jprogram.isJavaLangString(enclosingTypeOfCalledMethod) && !calledMethod.isStatic()) {
      logError("JSNI method %s attempts to call method %s. Only static methods from " +
              "java.lang.String can be called from JSNI.",
          currentJsniMethod.getQualifiedName(),
          calledMethod.getQualifiedName());
    } else if (jprogram.isJavaLangObject(enclosingTypeOfCalledMethod) && !calledMethod.isStatic()) {
      log(Type.WARN, "JSNI method %s calls method %s. Instance java.lang.Object methods should " +
              "not be called on String, Array or JSO instances.",
          currentJsniMethod.getQualifiedName(),
          calledMethod.getQualifiedName());
    }
    return super.visit(x, ctx);
  }

  private void log(Type type, String format, Object... args) {
    logger.log(type, String.format(format, args));
    hasErrors |= type == Type.ERROR;
  }

  private void logError(String format, Object... args) {
    log(Type.ERROR, format, args);
  }

  private boolean isJsoInterface(JDeclaredType type) {
    return jprogram.typeOracle.isSingleJsoImpl(type)
        || jprogram.typeOracle.isDualJsoInterface(type);
  }

  private boolean isNonStaticJsoClassDispatch(JMethod method, JDeclaredType enclosingType) {
    return !method.isStatic() && enclosingType.isJsoType();
  }
}
