/*
 * Copyright (C) 2010 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.doclava;

import com.google.doclava.apicheck.ApiParseException;
import com.google.clearsilver.jsilver.data.Data;
import java.util.Comparator;
import java.util.ArrayList;

public class FieldInfo extends MemberInfo {
  public static final Comparator<FieldInfo> comparator = new Comparator<FieldInfo>() {
    public int compare(FieldInfo a, FieldInfo b) {
      return a.name().compareTo(b.name());
    }
  };

  public FieldInfo(String name, ClassInfo containingClass, ClassInfo realContainingClass,
      boolean isPublic, boolean isProtected, boolean isPackagePrivate, boolean isPrivate,
      boolean isFinal, boolean isStatic, boolean isTransient, boolean isVolatile,
      boolean isSynthetic, TypeInfo type, String rawCommentText, Object constantValue,
      SourcePositionInfo position, ArrayList<AnnotationInstanceInfo> annotations) {
    super(rawCommentText, name, null, containingClass, realContainingClass, isPublic, isProtected,
          isPackagePrivate, isPrivate, isFinal, isStatic, isSynthetic, chooseKind(isFinal, isStatic, constantValue),
        position, annotations);
    mIsTransient = isTransient;
    mIsVolatile = isVolatile;
    mType = type;
    mConstantValue = constantValue;
  }

  public FieldInfo cloneForClass(ClassInfo newContainingClass) {
    return new FieldInfo(name(), newContainingClass, realContainingClass(), isPublic(),
        isProtected(), isPackagePrivate(), isPrivate(), isFinal(), isStatic(), isTransient(),
        isVolatile(), isSynthetic(), mType, getRawCommentText(), mConstantValue, position(),
        annotations());
  }

  static String chooseKind(boolean isFinal, boolean isStatic, Object constantValue)
  {
    return isConstant(isFinal, isStatic, constantValue) ? "constant" : "field";
  }
  
  public String qualifiedName() {
    String parentQName
        = (containingClass() != null) ? (containingClass().qualifiedName() + ".") : "";
    return parentQName + name();
  }

  public TypeInfo type() {
    return mType;
  }

  static boolean isConstant(boolean isFinal, boolean isStatic, Object constantValue)
  {
    /*
     * Note: There is an ambiguity in the doc API that prevents us
     * from distinguishing a constant-null from the lack of a
     * constant at all. We err on the side of treating all null
     * constantValues as meaning that the field is not a constant,
     * since having a static final field assigned to null is both
     * unusual and generally pretty useless.
     */
    return isFinal && isStatic && (constantValue != null);
  }

  public boolean isConstant() {
    return isConstant(isFinal(), isStatic(), mConstantValue);
  }

  public TagInfo[] firstSentenceTags() {
    return comment().briefTags();
  }

  public TagInfo[] inlineTags() {
    return comment().tags();
  }

  public Object constantValue() {
    return mConstantValue;
  }

  public String constantLiteralValue() {
    return constantLiteralValue(mConstantValue);
  }

  public void setDeprecated(boolean deprecated) {
    mDeprecatedKnown = true;
    mIsDeprecated = deprecated;
  }
  
  public boolean isDeprecated() {
    if (!mDeprecatedKnown) {
      boolean commentDeprecated = comment().isDeprecated();
      boolean annotationDeprecated = false;
      for (AnnotationInstanceInfo annotation : annotations()) {
        if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
          annotationDeprecated = true;
          break;
        }
      }

      if (commentDeprecated != annotationDeprecated) {
        Errors.error(Errors.DEPRECATION_MISMATCH, position(), "Field "
            + mContainingClass.qualifiedName() + "." + name()
            + ": @Deprecated annotation and @deprecated comment do not match");
      }

      mIsDeprecated = commentDeprecated | annotationDeprecated;
      mDeprecatedKnown = true;
    }
    return mIsDeprecated;
  }

  public static String constantLiteralValue(Object val) {
    String str = null;
    if (val != null) {
      if (val instanceof Boolean || val instanceof Byte || val instanceof Short
          || val instanceof Integer) {
        str = val.toString();
      }
      // catch all special values
      else if (val instanceof Double) {
        str = canonicalizeFloatingPoint(val.toString(), "");
      } else if (val instanceof Float) {
        str = canonicalizeFloatingPoint(val.toString(), "f");
      } else if (val instanceof Long) {
        str = val.toString() + "L";
      } else if (val instanceof Character) {
        str = String.format("\'\\u%04x\'", val);
        System.out.println("str=" + str);
      } else if (val instanceof String) {
        str = "\"" + javaEscapeString((String) val) + "\"";
      } else {
        str = "<<<<" + val.toString() + ">>>>";
      }
    }
    if (str == null) {
      str = "null";
    }
    return str;
  }

  /**
   * Returns a canonical string representation of a floating point
   * number. The representation is suitable for use as Java source
   * code. This method also addresses bug #4428022 in the Sun JDK.
   */
  private static String canonicalizeFloatingPoint(String val, String suffix) {
    if (val.equals("Infinity")) {
      return "(1.0" + suffix + "/0.0" + suffix + ")";
    } else if (val.equals("-Infinity")) {
      return "(-1.0" + suffix + "/0.0" + suffix + ")";
    } else if (val.equals("NaN")) {
      return "(0.0" + suffix + "/0.0" + suffix + ")";
    }

    String str = val.toString();
    if (str.indexOf('E') != -1) {
      return str + suffix;
    }

    // 1.0 is the only case where a trailing "0" is allowed.
    // 1.00 is canonicalized as 1.0.
    int i = str.length() - 1;
    int d = str.indexOf('.');
    while (i >= d + 2 && str.charAt(i) == '0') {
      str = str.substring(0, i--);
    }
    return str + suffix;
  }

  public static String javaEscapeString(String str) {
    String result = "";
    final int N = str.length();
    for (int i = 0; i < N; i++) {
      char c = str.charAt(i);
      if (c == '\\') {
        result += "\\\\";
      } else if (c == '\t') {
        result += "\\t";
      } else if (c == '\b') {
        result += "\\b";
      } else if (c == '\r') {
        result += "\\r";
      } else if (c == '\n') {
        result += "\\n";
      } else if (c == '\f') {
        result += "\\f";
      } else if (c == '\'') {
        result += "\\'";
      } else if (c == '\"') {
        result += "\\\"";
      } else if (c >= ' ' && c <= '~') {
        result += c;
      } else {
        result += String.format("\\u%04x", new Integer((int) c));
      }
    }
    return result;
  }

  public static String javaUnescapeString(String str) throws ApiParseException {
    final int N = str.length();
    check: {
      for (int i=0; i<N; i++) {
        final char c = str.charAt(i);
        if (c == '\\') {
          break check;
        }
      }
      return str;
    }

    final StringBuilder buf = new StringBuilder(str.length());
    char escaped = 0;
    final int START = 0;
    final int CHAR1 = 1;
    final int CHAR2 = 2;
    final int CHAR3 = 3;
    final int CHAR4 = 4;
    final int ESCAPE = 5;
    int state = START;

    for (int i=0; i<N; i++) {
      final char c = str.charAt(i);
      switch (state) {
        case START:
          if (c == '\\') {
            state = ESCAPE;
          } else {
            buf.append(c);
          }
          break;
        case ESCAPE:
          switch (c) {
            case '\\':
              buf.append('\\');
              state = START;
              break;
            case 't':
              buf.append('\t');
              state = START;
              break;
            case 'b':
              buf.append('\b');
              state = START;
              break;
            case 'r':
              buf.append('\r');
              state = START;
              break;
            case 'n':
              buf.append('\n');
              state = START;
              break;
            case 'f':
              buf.append('\f');
              state = START;
              break;
            case '\'':
              buf.append('\'');
              state = START;
              break;
            case '\"':
              buf.append('\"');
              state = START;
              break;
            case 'u':
              state = CHAR1;
              escaped = 0;
              break;
          }
          break;
        case CHAR1:
        case CHAR2:
        case CHAR3:
        case CHAR4:
          escaped <<= 4;
          if (c >= '0' && c <= '9') {
            escaped |= c - '0';
          } else if (c >= 'a' && c <= 'f') {
            escaped |= 10 + (c - 'a');
          } else if (c >= 'A' && c <= 'F') {
            escaped |= 10 + (c - 'A');
          } else {
            throw new ApiParseException("bad escape sequence: '" + c + "' at pos " + i + " in: \""
                + str + "\"");
          }
          if (state == CHAR4) {
            buf.append(escaped);
            state = START;
          } else {
            state++;
          }
          break;
      }
    }
    if (state != START) {
      throw new ApiParseException("unfinished escape sequence: " + str);
    }
    return buf.toString();
  }

  public void makeHDF(Data data, String base) {
    data.setValue(base + ".kind", kind());
    type().makeHDF(data, base + ".type");
    data.setValue(base + ".name", name());
    data.setValue(base + ".href", htmlPage());
    data.setValue(base + ".anchor", anchor());
    TagInfo.makeHDF(data, base + ".shortDescr", firstSentenceTags());
    TagInfo.makeHDF(data, base + ".descr", inlineTags());
    TagInfo.makeHDF(data, base + ".deprecated", comment().deprecatedTags());
    TagInfo.makeHDF(data, base + ".seeAlso", comment().seeTags());
    data.setValue(base + ".since", getSince());
    if (isDeprecated()) {
      data.setValue(base + ".deprecatedsince", getDeprecatedSince());
    }
    data.setValue(base + ".final", isFinal() ? "final" : "");
    data.setValue(base + ".static", isStatic() ? "static" : "");
    if (isPublic()) {
      data.setValue(base + ".scope", "public");
    } else if (isProtected()) {
      data.setValue(base + ".scope", "protected");
    } else if (isPackagePrivate()) {
      data.setValue(base + ".scope", "");
    } else if (isPrivate()) {
      data.setValue(base + ".scope", "private");
    }
    Object val = mConstantValue;
    if (val != null) {
      String dec = null;
      String hex = null;
      String str = null;

      if (val instanceof Boolean) {
        str = ((Boolean) val).toString();
      } else if (val instanceof Byte) {
        dec = String.format("%d", val);
        hex = String.format("0x%02x", val);
      } else if (val instanceof Character) {
        dec = String.format("\'%c\'", val);
        hex = String.format("0x%04x", val);
      } else if (val instanceof Double) {
        str = ((Double) val).toString();
      } else if (val instanceof Float) {
        str = ((Float) val).toString();
      } else if (val instanceof Integer) {
        dec = String.format("%d", val);
        hex = String.format("0x%08x", val);
      } else if (val instanceof Long) {
        dec = String.format("%d", val);
        hex = String.format("0x%016x", val);
      } else if (val instanceof Short) {
        dec = String.format("%d", val);
        hex = String.format("0x%04x", val);
      } else if (val instanceof String) {
        str = "\"" + ((String) val) + "\"";
      } else {
        str = "";
      }

      if (dec != null && hex != null) {
        data.setValue(base + ".constantValue.dec", Doclava.escape(dec));
        data.setValue(base + ".constantValue.hex", Doclava.escape(hex));
      } else {
        data.setValue(base + ".constantValue.str", Doclava.escape(str));
        data.setValue(base + ".constantValue.isString", "1");
      }
    }

    AnnotationInstanceInfo.makeLinkListHDF(
      data,
      base + ".showAnnotations",
      showAnnotations().toArray(new AnnotationInstanceInfo[showAnnotations().size()]));

    setFederatedReferences(data, base);
  }

  @Override
  public boolean isExecutable() {
    return false;
  }

  public boolean isTransient() {
    return mIsTransient;
  }

  public boolean isVolatile() {
    return mIsVolatile;
  }
  
  // Check the declared value with a typed comparison, not a string comparison,
  // to accommodate toolchains with different fp -> string conversions.
  private boolean valueEquals(FieldInfo other) {
    if ((mConstantValue == null) != (other.mConstantValue == null)) {
      return false;
    }
    
    // Null values are considered equal
    if (mConstantValue == null) {
      return true;
    }

    return mType.equals(other.mType)
        && mConstantValue.equals(other.mConstantValue);
  }
  
  public boolean isConsistent(FieldInfo fInfo) {
    boolean consistent = true;
    if (!mType.equals(fInfo.mType)) {
      Errors.error(Errors.CHANGED_TYPE, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed type from " + mType + " to " + fInfo.mType);
      consistent = false;
    } else if (!this.valueEquals(fInfo)) {
      Errors.error(Errors.CHANGED_VALUE, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed value from " + mConstantValue + " to " + fInfo.mConstantValue);
      consistent = false;
    }

    if (!scope().equals(fInfo.scope())) {
      Errors.error(Errors.CHANGED_SCOPE, fInfo.position(), "Method " + fInfo.qualifiedName()
          + " changed scope from " + this.scope() + " to " + fInfo.scope());
      consistent = false;
    }

    if (mIsStatic != fInfo.mIsStatic) {
      Errors.error(Errors.CHANGED_STATIC, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed 'static' qualifier");
      consistent = false;
    }

    if (!mIsFinal && fInfo.mIsFinal) {
      Errors.error(Errors.ADDED_FINAL, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has added 'final' qualifier");
      consistent = false;
    } else if (mIsFinal && !fInfo.mIsFinal) {
      Errors.error(Errors.REMOVED_FINAL, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has removed 'final' qualifier");
      consistent = false;
    }

    if (mIsTransient != fInfo.mIsTransient) {
      Errors.error(Errors.CHANGED_TRANSIENT, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed 'transient' qualifier");
      consistent = false;
    }

    if (mIsVolatile != fInfo.mIsVolatile) {
      Errors.error(Errors.CHANGED_VOLATILE, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed 'volatile' qualifier");
      consistent = false;
    }

    if (isDeprecated() != fInfo.isDeprecated()) {
      Errors.error(Errors.CHANGED_DEPRECATED, fInfo.position(), "Field " + fInfo.qualifiedName()
          + " has changed deprecation state " + isDeprecated() + " --> " + fInfo.isDeprecated());
      consistent = false;
    }

    return consistent;
  }

  public boolean hasValue() {
      return mHasValue;
  }

  public void setHasValue(boolean hasValue) {
      mHasValue = hasValue;
  }

  boolean mIsTransient;
  boolean mIsVolatile;
  boolean mDeprecatedKnown;
  boolean mIsDeprecated;
  boolean mHasValue;
  TypeInfo mType;
  Object mConstantValue;
}
