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

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.GeneratedUnit;
import com.google.gwt.dev.javac.JdtCompiler.AdditionalTypeProviderDelegate;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;

/**
 * Tests that a AdditionalTypeProviderDelegate correctly gets control when an unknown
 * class is found, and that source for an unknown class gets correctly parsed.
 */
public class AdditionalTypeProviderDelegateTest extends OptimizerTestBase {

  /**
   * Compilation unit for a class generated at runtime when an unknown
   * reference appears.
   */
  private class JavaWrapperCompilationUnit implements GeneratedUnit {
    private final long createTime = System.currentTimeMillis();

    public String optionalFileLocation() {
      // The named file location requires a non-Java extension,
      // or else the file won't get compiled correctly.
      return "myPackage/InsertedClass.notjava";
    }

    public String getStrongHash() {
      return "InsertedClass";
    }

    public long creationTime() {
      return createTime;
    }

   public String getSource() {
      String classSource = 
          "package myPackage;\n" +
          "public class InsertedClass {\n" +
          "  public static int getSmallNumber() {\n" +
          "    return 5;\n" +
          "  }\n" +
          "}";
      return classSource;
    }
   
    public String getTypeName() {
      return "myPackage.InsertedClass";
    }
    
    public long getSourceToken() {
      return -1;
    }
  }

   public boolean insertInsertedClass = false;

   public void setUp() {
     // Create a source class that passes fine (just to test infrastructure.)
     sourceOracle.addOrReplace(new MockJavaResource("test.A") {
       @Override
       public CharSequence getContent() {
         StringBuffer code = new StringBuffer();
         code.append("package test;\n");
         code.append("class A {\n");
         code.append("  void myFunc() {\n");
         code.append("  }\n");
         code.append("}\n");
         return code;
       }
     });
     
     // Create a source file containing a reference to a class in another
     // package that we don't yet know about.  That code will be inserted
     // by the AdditionalTypeProviderDelegate.
     sourceOracle.addOrReplace(new MockJavaResource("test.B") {
       @Override
       public CharSequence getContent() {
         StringBuffer code = new StringBuffer();
         code.append("package test;\n");
         code.append("import myPackage.InsertedClass;");
         code.append("class B {\n");
         code.append("  int func() {\n");
         // Reference an unknown class that will be substituted on the fly.
         code.append("    return myPackage.InsertedClass.getSmallNumber();\n");
         code.append("  }\n");
         code.append("}\n");
         return code;
       }
     });
     
     // Create a source file containing a reference to a class in another
     // package, but that lacks an import directive.  Are we creating the
     // class anyway?
     sourceOracle.addOrReplace(new MockJavaResource("test.B1") {
       @Override
       public CharSequence getContent() {
         StringBuffer code = new StringBuffer();
         code.append("package test;\n");
         code.append("class B1 {\n");
         code.append("  int func() {\n");
         // Reference an unknown class that will be substituted on the fly.
         code.append("    return myPackage.InsertedClass.getSmallNumber();\n");
         code.append("  }\n");
         code.append("}\n");
         return code;
       }
     });
  }

  public void testInsertedClass() throws UnableToCompleteException {
    JProgram program = compileSnippet("void", "new test.B().func();");
    
    // Make sure the compiled classes appeared.
    JDeclaredType bType = findType(program, "test.B");
    assertNotNull("Unknown type B", bType);
    JDeclaredType insertedClassType = findType(program, "myPackage.InsertedClass");
    assertNotNull("Unknown type InsertedClass", insertedClassType);  
  }
  
  public void testInsertedClass2() throws UnableToCompleteException {
    JProgram program = compileSnippet("void", "new test.B1().func();");
    
    // Make sure the compiled classes appeared.
    JDeclaredType bType = findType(program, "test.B1");
    assertNotNull("Unknown type B1", bType);
    JDeclaredType insertedClassType = findType(program, "myPackage.InsertedClass");
    assertNotNull("Unknown type InsertedClass", insertedClassType);  
  }

  // Make sure regular code not using the AdditionalTypeProviderDelegate still works.
  public void testSimpleParse() throws UnableToCompleteException {
    JProgram program = compileSnippet("void", "new test.A();");
    JDeclaredType goodClassType = findType(program, "test.A");
    assertNotNull("Unknown class A", goodClassType);
  }

  public void testUnknownClass() {
    // Create a source file containing a reference to an unknown class.
    sourceOracle.addOrReplace(new MockJavaResource("test.C") {
      @Override
      public CharSequence getContent() {
        StringBuffer code = new StringBuffer();
        code.append("package test;\n");
        code.append("import myPackage.UnknownClass;");
        code.append("class C {\n");
        code.append("  int func() {\n");
        // Reference an unknown class.
        code.append("    return myPackage.UnknownClass.getSmallNumber();\n");
        code.append("  }\n");
        code.append("}\n");
        return code;
      }
    });
    try {
      compileSnippet("void", "new test.C();");
      fail("Shouldn't have compiled");
    } catch (UnableToCompleteException expected) {
    }
  }

  public void testUnknownClassNoImport() {
    // Create a source file with a reference to an unknown class and no
    // import statement.
    sourceOracle.addOrReplace(new MockJavaResource("test.D") {
      @Override
      public CharSequence getContent() {
        StringBuffer code = new StringBuffer();
        code.append("package test;\n");
        code.append("class D {\n");
        code.append("  int func() {\n");
        // Reference an unknown class.
        code.append("    return myPackage.UnknownClass.getSmallNumber();\n");
        code.append("  }\n");
        code.append("}\n");
        return code;
      }
    });
    try {
      compileSnippet("void", "new test.D();");
      fail("Shouldn't have compiled");
    } catch (UnableToCompleteException expected) {
    }
  }

  @Override
  protected AdditionalTypeProviderDelegate getAdditionalTypeProviderDelegate() {
    // We'll provide a simple compiler delegate that will provide source
    // for a class called myPackage.InsertedClass.
    return new AdditionalTypeProviderDelegate() {
      public boolean doFindAdditionalPackage(String slashedPackageName) {
        if (slashedPackageName.compareTo("myPackage") == 0) {
            return true;
        }
        return false;
      }

      public GeneratedUnit doFindAdditionalType(String binaryName) {
        if (binaryName.compareTo("myPackage/InsertedClass") == 0) {
          return new JavaWrapperCompilationUnit();
      }
      return null;
      }
    };
  }

  protected boolean optimizeMethod(JProgram program, JMethod method) {
    return false;
  }
}
