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

import com.google.gwt.core.ext.typeinfo.JniConstants;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A parsed Java reference from within a JSNI method.
 */
public class JsniRef {
  /**
   * Special field name for referring to a class literal.
   */
  public static final String CLASS = "class";

  /**
   * Special method name for a class constructor.
   */
  public static final String NEW = "new";

  /**
   * A parameter list indicating a match to any overload.
   */
  public static final String WILDCARD_PARAM_LIST = "*";

  /**
   * A regex pattern for a Java reference in JSNI code. Its groups are:
   * <ol>
   * <li>the class name
   * <li>the field or method name
   * <li>the method parameter types, including the surrounding parentheses
   * <li>the method parameter types, excluding the parentheses
   * </ol>
   */
  private static Pattern JsniRefPattern = Pattern.compile("@?([^:]+)::([^(]+)(\\((.*)\\))?");

  /**
   * Parse a Java reference from JSNI code. This parser is forgiving; it does
   * not always detect invalid references. If the refString is improperly
   * formatted, returns null.
   */
  public static JsniRef parse(String refString) {
    Matcher matcher = JsniRefPattern.matcher(refString);
    if (!matcher.matches()) {
      return null;
    }

    String className = matcher.group(1);
    String memberName = matcher.group(2);
    String paramTypesString = null;
    String[] paramTypes = null;
    if (matcher.group(3) != null) {
      paramTypesString = matcher.group(4);
      if (!paramTypesString.equals(WILDCARD_PARAM_LIST)) {
        paramTypes = computeParamTypes(paramTypesString);
        if (paramTypes == null) {
          return null;
        }
      }
    }
    return new JsniRef(className, memberName, paramTypesString, paramTypes);
  }

  private static String[] computeParamTypes(String paramTypesString) {
    ArrayList<String> types = new ArrayList<String>();
    StringBuilder nextType = new StringBuilder();
    boolean inRef = false;
    for (char c : paramTypesString.toCharArray()) {
      nextType.append(c);
      if (inRef) {
        if (c == JniConstants.DESC_REF_END) {
          types.add(nextType.toString());
          nextType.setLength(0);
          inRef = false;
        }
      } else {
        switch (c) {
          case JniConstants.DESC_BOOLEAN:
          case JniConstants.DESC_BYTE:
          case JniConstants.DESC_CHAR:
          case JniConstants.DESC_DOUBLE:
          case JniConstants.DESC_FLOAT:
          case JniConstants.DESC_INT:
          case JniConstants.DESC_LONG:
          case JniConstants.DESC_SHORT:
          case JniConstants.DESC_VOID:
            types.add(nextType.toString());
            nextType.setLength(0);
            break;

          case JniConstants.DESC_ARRAY:
            // Nothing special to do.
            break;

          case JniConstants.DESC_REF:
            inRef = true;
            break;

          default:
            // Bad input.
            return null;
        }
      }
    }

    return types.toArray(Empty.STRINGS);
  }

  private final String className;
  private final String memberName;
  private final String[] paramTypes;
  private final String paramTypesString;

  protected JsniRef(String className, String memberName,
      String paramTypesString, String[] paramTypes) {
    this.className = className;
    this.memberName = memberName;
    this.paramTypesString = paramTypesString;
    this.paramTypes = paramTypes;
  }

  public String className() {
    return className;
  }

  @Override
  public boolean equals(Object obj) {
    return (obj instanceof JsniRef) && toString().equals(obj.toString());
  }

  @Override
  public int hashCode() {
    return toString().hashCode();
  }

  public boolean isField() {
    return paramTypesString == null;
  }

  public boolean isMethod() {
    return paramTypesString != null;
  }

  /**
   * Whether this method reference matches all overloads of the specified class
   * and method name. Only valid for method references.
   */
  public boolean matchesAnyOverload() {
    return paramTypesString.equals(WILDCARD_PARAM_LIST);
  }

  public String memberName() {
    return memberName;
  }

  public String memberSignature() {
    String ret = memberName;
    if (isMethod()) {
      ret += "(" + paramTypesString + ")";
    }
    return ret;
  }

  /**
   * Return the list of parameter types for the method referred to by this
   * reference. Only valid for method references where
   * {@link #matchesAnyOverload()} is false.
   */
  public String[] paramTypes() {
    assert !matchesAnyOverload();
    return paramTypes;
  }

  public String paramTypesString() {
    return paramTypesString;
  }

  @Override
  public String toString() {
    return "@" + className + "::" + memberSignature();
  }
}
