/*
 * Copyright 2011 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.javac.testing.impl.MockJavaResource;

import org.eclipse.jdt.core.compiler.CategorizedProblem;

/**
 * Tests for {@link BytecodeSignatureMaker}
 */
public class BytecodeSignatureMakerTest extends CompilationStateTestBase {
  static final String CLASS_DEP_TYPE_NAME = "test.ClassDependency";

  public void testClassDependencySignature() {
    final MockJavaResource CLASS_DEP_ORIG =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    // A verbatim copy of CLASS_DEP_ORIG
    final MockJavaResource CLASS_DEP_NO_CHANGE =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_NO_PRIVATE =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            // Missing fieldPrivate
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            // Missing methodPrivate
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_NO_PROTECTED_FIELD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            // missing fieldProtected
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_NO_DEFAULT_FIELD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            // missing fieldDefault
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_NO_PUBLIC_FIELD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            // missing public field
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_FIELD_VALUE_CHANGE =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            // Value was 100
            code.append("  static public final int fieldPublicStatic = 99;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_ORDER =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            // re-ordered this field
            code.append("  public int fieldPublic;\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            // re-ordered this method
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_INNER =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            // Added an inner class definition
            code.append("  public static class IgnoreMe {\n");
            code.append("    private int ignoreThisMember;\n");
            code.append("  }\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_DEPRECATED_FIELD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  @Deprecated\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_DEPRECATED_METHOD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  @Deprecated\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };

    final MockJavaResource CLASS_DEP_ANNOTATED_FIELD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  @TestAnnotation(\"Foo\")\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_ANNOTATED_METHOD =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  @TestAnnotation(\"Foo\")\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };
    final MockJavaResource CLASS_DEP_JAVADOC =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  /** a static field */\n");
            code.append("  static public final int fieldPublicStatic = 100;\n");
            code.append("  /** a public field */\n");
            code.append("  public int fieldPublic;\n");
            code.append("  protected int fieldProtected;\n");
            code.append("  int fieldDefault;\n");
            code.append("  private int fieldPrivate;\n");
            code.append("  /** a public method */\n");
            code.append("  public int methodPublic() {return 1;};\n");
            code.append("  protected int methodProtected(String arg) {return 1;};\n");
            code.append("  int methodDefault() {return 1;};\n");
            code.append("  private int methodPrivate(){return 1;};\n");
            code.append("}");
            return code;
          }
        };

    final MockJavaResource TEST_ANNOTATION =
        new MockJavaResource("test.TestAnnotation") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public @interface TestAnnotation {\n");
            code.append("  String value();");
            code.append("}\n");
            return code;
          }
        };
    CompiledClass originalClass = buildClass(CLASS_DEP_ORIG);
    assertNotNull(originalClass);

    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_NO_CHANGE));
    assertSignaturesNotEqual(originalClass, buildClass(CLASS_DEP_NO_PRIVATE));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_NO_PUBLIC_FIELD));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_NO_PROTECTED_FIELD));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_NO_DEFAULT_FIELD));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_FIELD_VALUE_CHANGE));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_ORDER));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_INNER));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_DEPRECATED_FIELD));
    assertSignaturesEqual(originalClass,
        buildClass(CLASS_DEP_DEPRECATED_METHOD));

    oracle.add(TEST_ANNOTATION);
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_ANNOTATED_FIELD));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_ANNOTATED_METHOD));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_JAVADOC));
  }

  public void testClassDependencySignatureWithExceptions() {
    MockJavaResource ILLEGAL_STATE_EXCEPTION =
        new MockJavaResource("java.lang.IllegalStateException") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package java.lang;\n");
            code.append("public class IllegalStateException extends Throwable {}\n");
            return code;
          }
        };
    MockJavaResource NUMBER_FORMAT_EXCEPTION =
        new MockJavaResource("java.lang.NumberFormatException") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package java.lang;\n");
            code.append("public class NumberFormatException extends Throwable {}\n");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_EXCEPTION_ORIG =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  public int methodPublic(String arg) ");
            code.append("      throws IllegalStateException, NumberFormatException {");
            code.append("    return 1;\n");
            code.append("  }\n");
            code.append("}\n");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_EXCEPTION_MOD1 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            // no exceptions declared
            code.append("  public int methodPublic(String arg) {return 1;};\n");
            code.append("}");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_EXCEPTION_MOD2 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            // one exception declared
            code.append("  public int methodPublic(String arg)");
            code.append("     throws IllegalStateException {");
            code.append("    return 1;\n");
            code.append("  }\n");
            code.append("}");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_EXCEPTION_MOD3 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency {\n");
            code.append("  public int methodPublic(String arg)");
            // order of declared exceptions is flipped
            code.append("     throws NumberFormatException, IllegalStateException {");
            code.append("    return 1;\n");
            code.append("  }\n");
            code.append("}");
            return code;
          }
        };

    oracle.add(ILLEGAL_STATE_EXCEPTION);
    oracle.add(NUMBER_FORMAT_EXCEPTION);
    CompiledClass originalClass = buildClass(CLASS_DEP_EXCEPTION_ORIG);
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_EXCEPTION_MOD1));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_EXCEPTION_MOD2));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_EXCEPTION_MOD3));
  }

  public void testClassDependencySignatureWithGenerics() {
    MockJavaResource CLASS_DEP_GENERIC_ORIG =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("public class ClassDependency<T> {\n");
            code.append("  public int methodPublic(T arg) {return 1;};\n");
            code.append("}");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_GENERIC_PARAMETERIZED =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("import java.util.Map;");
            code.append("public class ClassDependency<T extends Map> {\n");
            code.append("  public int methodPublic(T arg) {return 1;};\n");
            code.append("}");
            return code;
          }
        };
    CompiledClass originalClass = buildClass(CLASS_DEP_GENERIC_ORIG);
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_GENERIC_PARAMETERIZED));
  }

  public void testClassDependencySignatureWithInterfaces() {
    MockJavaResource CLASS_DEP_INTERFACE_ORIG =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("import java.util.Map;");
            code.append("import java.util.Collection;");
            code.append("public class ClassDependency implements Map, Collection {\n");
            code.append("  public int methodPublic(String arg) { return 1;}\n");
            code.append("}\n");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_INTERFACE_MOD1 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("import java.util.Map;");
            code.append("import java.util.Collection;");
            // no interfaces
            code.append("public class ClassDependency {\n");
            code.append("  public int methodPublic(String arg) { return 1;}\n");
            code.append("}\n");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_INTERFACE_MOD2 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("import java.util.Map;");
            code.append("import java.util.Collection;");
            // only one interface
            code.append("public class ClassDependency implements Map {\n");
            code.append("  public int methodPublic(String arg) { return 1;}\n");
            code.append("}\n");
            return code;
          }
        };
    MockJavaResource CLASS_DEP_INTERFACE_MOD3 =
        new MockJavaResource(CLASS_DEP_TYPE_NAME) {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package test;\n");
            code.append("import java.util.Map;");
            code.append("import java.util.Collection;");
            // flipped order of interface decls
            code.append("public class ClassDependency implements Collection, Map {\n");
            code.append("  public int methodPublic(String arg) { return 1;}\n");
            code.append("}\n");
            return code;
          }
        };
    CompiledClass originalClass = buildClass(CLASS_DEP_INTERFACE_ORIG);
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_INTERFACE_MOD1));
    assertSignaturesNotEqual(originalClass,
        buildClass(CLASS_DEP_INTERFACE_MOD2));
    assertSignaturesEqual(originalClass, buildClass(CLASS_DEP_INTERFACE_MOD3));
  }

  private void assertSignaturesEqual(CompiledClass original,
      CompiledClass updated) {
    String originalSignature =
        BytecodeSignatureMaker.getCompileDependencySignature(original.getBytes());
    String updatedSignature =
        BytecodeSignatureMaker.getCompileDependencySignature(updated.getBytes());
    if (!originalSignature.equals(updatedSignature)) {
      String originalRaw =
          BytecodeSignatureMaker.getCompileDependencyRawSignature(original.getBytes());
      String updatedRaw =
          BytecodeSignatureMaker.getCompileDependencyRawSignature(updated.getBytes());
      fail("Signatures don't match.  raw data expected=<" + originalRaw
          + "> actual=<" + updatedRaw + ">");
    }
  }

  private void assertSignaturesNotEqual(CompiledClass original,
      CompiledClass updated) {
    String originalSignature =
        BytecodeSignatureMaker.getCompileDependencySignature(original.getBytes());
    String updatedSignature =
        BytecodeSignatureMaker.getCompileDependencySignature(updated.getBytes());
    if (originalSignature.equals(updatedSignature)) {
      String originalRaw =
          BytecodeSignatureMaker.getCompileDependencyRawSignature(original.getBytes());
      String updatedRaw =
          BytecodeSignatureMaker.getCompileDependencyRawSignature(updated.getBytes());
      fail("Signatures should not match.  raw data expected=<" + originalRaw
          + "> actual=<" + updatedRaw + ">");
    }
  }

  private CompiledClass buildClass(MockJavaResource resource) {
    oracle.addOrReplace(resource);
    this.rebuildCompilationState();
    CompilationUnit unit =
        state.getCompilationUnitMap().get(resource.getTypeName());
    assertNotNull(unit);
    String internalName = resource.getTypeName().replace(".", "/");
    CategorizedProblem[] problems = unit.getProblems();
    if (problems != null && problems.length != 0) {
      fail(problems[0].toString());
    }
    for (CompiledClass cc : unit.getCompiledClasses()) {
      if (cc.getInternalName().equals(internalName)) {
        return cc;
      }
    }
    fail("Couldn't find class " + internalName + " after compiling.");
    return null;
  }
}
