/*
 * 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.javac;

import com.google.gwt.dev.jjs.ast.HasJsInfo.JsMemberType;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JMember;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
import com.google.gwt.thirdparty.guava.common.collect.Lists;

import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;

import java.util.List;

/**
 * Utility functions to interact with JDT classes for JsInterop.
 */
public final class JsInteropUtil {
  public static final String UNUSABLE_BY_JS = "unusable-by-js";
  public static final String INVALID_JSNAME = "<invalid>";

  public static boolean isGlobal(String jsNamespace) {
    return "<global>".equals(jsNamespace);
  }

  public static boolean isWindow(String jsNamespace) {
    return "<window>".equals(jsNamespace);
  }

  public static String normalizeQualifier(String qualifier) {
    assert !qualifier.isEmpty();
    List<String> components = Lists.newArrayList(qualifier.split("\\."));
    if (isWindow(components.get(0))) {
      // Emit unqualified if '<window>' namespace was specified.
      components.remove(0);
    } else if (isGlobal(components.get(0))) {
      // Replace global with $wnd.
      components.set(0, "$wnd");
    } else {
      // still emit $wnd as rest implicitly points to global.
      components.add(0, "$wnd");
    }
    return Joiner.on('.').join(components);
  }

  public static void maybeSetJsInteropProperties(JDeclaredType type, Annotation[] annotations) {
    AnnotationBinding jsType = getInteropAnnotation(annotations, "JsType");
    String namespace = JdtUtil.getAnnotationParameterString(jsType, "namespace");
    String name = JdtUtil.getAnnotationParameterString(jsType, "name");
    boolean isJsNative = JdtUtil.getAnnotationParameterBoolean(jsType, "isNative", false);

    AnnotationBinding jsPackage = getInteropAnnotation(annotations, "JsPackage");
    String packageNamespace = JdtUtil.getAnnotationParameterString(jsPackage, "namespace");
    if (packageNamespace != null) {
      namespace = packageNamespace;
    }

    boolean isJsType = jsType != null;
    boolean isJsFunction = getInteropAnnotation(annotations, "JsFunction") != null;
    type.setJsTypeInfo(isJsType, isJsNative, isJsFunction, namespace, name, isJsType);
  }

  public static void maybeSetJsInteropProperties(
      JMethod method, boolean generateExport, Annotation... annotations) {
    AnnotationBinding annotation = getInteropAnnotation(annotations, "JsMethod");
    if (annotation == null) {
      annotation = getInteropAnnotation(annotations, "JsConstructor");
    }
    if (annotation == null) {
      annotation = getInteropAnnotation(annotations, "JsProperty");
    }

    boolean isPropertyAccessor = getInteropAnnotation(annotations, "JsProperty") != null;
    setJsInteropProperties(method, annotations, annotation, isPropertyAccessor, generateExport);
  }

  public static void maybeSetJsInteropProperties(JParameter parameter,  Annotation... annotations) {
    if (getInteropAnnotation(annotations, "JsOptional") != null) {
      parameter.setOptional();
    }
  }

  public static void maybeSetJsInteropProperties(
      JField field, boolean generateExport, Annotation... annotations) {
    AnnotationBinding annotation = getInteropAnnotation(annotations, "JsProperty");
    setJsInteropProperties(field, annotations, annotation, false, generateExport);
  }

  private static void setJsInteropProperties(JMember member, Annotation[] annotations,
      AnnotationBinding memberAnnotation, boolean isAccessor, boolean generateExport) {
    if (getInteropAnnotation(annotations, "JsOverlay") != null) {
      member.setJsOverlay();
    }

    if (getInteropAnnotation(annotations, "JsIgnore") != null) {
      return;
    }

    boolean isPublicMemberForJsType = member.getEnclosingType().isJsType() && member.isPublic();
    boolean memberForNativeType = member.getEnclosingType().isJsNative();
    if (memberAnnotation == null
        && (!isPublicMemberForJsType && !memberForNativeType || member.isJsOverlay())) {
      return;
    }

    String namespace = JdtUtil.getAnnotationParameterString(memberAnnotation, "namespace");
    String name = JdtUtil.getAnnotationParameterString(memberAnnotation, "name");
    JsMemberType memberType = getJsMemberType(member, isAccessor);
    member.setJsMemberInfo(memberType, namespace, name, generateExport);
  }

  private static JsMemberType getJsMemberType(JMember member, boolean isPropertyAccessor) {
    if (member instanceof JField) {
      return JsMemberType.PROPERTY;
    }
    if (member instanceof JConstructor) {
      return JsMemberType.CONSTRUCTOR;
    }
    if (isPropertyAccessor) {
      return getJsPropertyAccessorType((JMethod) member);
    }
    return JsMemberType.METHOD;
  }

  private static JsMemberType getJsPropertyAccessorType(JMethod method) {
    if (method.getParams().size() == 1 && method.getType() == JPrimitiveType.VOID) {
      return JsMemberType.SETTER;
    } else if (method.getParams().isEmpty()
        && (method.getType() != JPrimitiveType.VOID || isDebugger(method))) {
      return JsMemberType.GETTER;
    }
    return JsMemberType.UNDEFINED_ACCESSOR;
  }

  private static boolean isDebugger(JMethod method) {
    return method.isStatic()
        && method.getName().equals("debugger")
        && (method.isJsNative() || method.isAbstract());
  }

  private static AnnotationBinding getInteropAnnotation(Annotation[] annotations, String name) {
    return JdtUtil.getAnnotationByName(annotations, "jsinterop.annotations." + name);
  }

}
