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

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracleException;
import com.google.gwt.thirdparty.guava.common.base.Joiner;

/**
 * Tests for {@link TypeOracleUpdater} when provided sources.
 */
public class CompilationUnitTypeOracleUpdaterFromSourceTest extends TypeOracleUpdaterTestBase {

  protected CheckedJavaResource CU_HasSyntaxErrors = new CheckedJavaResource(
      "test", "HasSyntaxErrors", "NoSyntaxErrors") {
    @Override
    public void check(JClassType classInfo) {
      fail("This class should have been removed");
    }

    @Override
    public String getSource() {
      StringBuilder sb = new StringBuilder();
      sb.append("package test;\n");
      sb.append("class NoSyntaxErrors { }\n");
      sb.append("public class HasSyntaxErrors { a syntax error }\n");
      return sb.toString();
    }
  };

  protected CheckedJavaResource CU_HasUnresolvedSymbols = new CheckedJavaResource(
      "test", "Invalid", "Valid") {
    @Override
    public void check(JClassType classInfo) {
      fail("Both classes should have been removed");
    }

    @Override
    public String getSource() {
      StringBuilder sb = new StringBuilder();
      sb.append("package " + getPackageName() + ";\n");
      sb.append("public class Invalid extends NoSuchClass { }\n");
      sb.append("class Valid extends Object { }\n");
      return sb.toString();
    }
  };

  protected CheckedJavaResource CU_RefsInfectedCompilationUnit = new CheckedJavaResource(
      "test", "RefsInfectedCompilationUnit") {
    @Override
    public void check(JClassType classInfo) {
      fail("This class should should have been removed because it refers to a class in another compilation unit that had problems");
    }

    @Override
    public String getSource() {
      StringBuilder sb = new StringBuilder();
      sb.append("package test;\n");
      sb.append("public class RefsInfectedCompilationUnit extends Valid { }\n");
      return sb.toString();
    }
  };

   /**
   * Tests that refreshing with a unit that has errors does not cause new units
   * that reference unchanged units to be removed. The strategy is to add some
   * good units that reference each other and build a {@link TypeOracle}. Then
   * we add some new units that have errors as well as some units that reference
   * old units which did not have errors. This ensures that the correct units
   * are pruned from the type oracle in the case where we encounter units with
   * errors.
   */
  public void testRefreshWithErrors() throws TypeOracleException {
    // Add Object
    StringBuilder sb = new StringBuilder();
    sb.append("package java.lang;");
    sb.append("public class Object { }");
    addResource("java.lang.Object", sb);

    // Add UnmodifiedClass that will never change.
    sb = new StringBuilder();
    sb.append("package test.refresh.with.errors;");
    sb.append("public class UnmodifiedClass { }");
    addResource("test.refresh.with.errors.UnmodifiedClass", sb);

    // Add GoodClass that references a class that will go bad.
    sb = new StringBuilder();
    sb.append("package test.refresh.with.errors;\n");
    sb.append("public class GoodClass {\n");
    sb.append("  ClassThatWillGoBad ctwgb;\n");
    sb.append("}\n");
    addResource("test.refresh.with.errors.GoodClass", sb);

    // Add ClassThatWillGoBad that goes bad on the next refresh.
    MutableJavaResource unitThatWillGoBad = new MutableJavaResource(
        "test.refresh.with.errors",
        "test.refresh.with.errors.ClassThatWillGoBad") {

      private String source = "package test.refresh.with.errors;\n"
          + "public class ClassThatWillGoBad { }\n";

      @Override
      public String getSource() {
        return source;
      }

      @Override
      public void touch() {
        super.touch();
        source = "This will cause a syntax error.";
      }
    };

    resources.add(unitThatWillGoBad);

    buildTypeOracle();

    assertNotNull(typeOracle.findType("test.refresh.with.errors.UnmodifiedClass"));
    assertNotNull(typeOracle.findType("test.refresh.with.errors.GoodClass"));
    assertNotNull(typeOracle.findType("test.refresh.with.errors.ClassThatWillGoBad"));

    // Add AnotherGoodClass that references a
    // class that was not recompiled.
    sb = new StringBuilder();
    sb.append("package test.refresh.with.errors;\n");
    sb.append("public class AnotherGoodClass {\n");
    sb.append("  UnmodifiedClass uc; // This will cause the runaway pruning.\n");
    sb.append("}\n");
    addResource("test.refresh.with.errors.AnotherGoodClass", sb);

    // Add BadClass that has errors and originally
    // forced issue 2238.
    sb = new StringBuilder();
    sb.append("package test.refresh.with.errors;\n");
    sb.append("public class BadClass {\n");
    sb.append("  This will trigger a syntax error.\n");
    sb.append("}\n");
    addResource("test.refresh.with.errors.BadClass", sb);

    // Now this cup should cause errors.
    unitThatWillGoBad.touch();

    buildTypeOracle();

    assertNotNull(typeOracle.findType("test.refresh.with.errors.UnmodifiedClass"));
    assertNotNull(typeOracle.findType("test.refresh.with.errors.AnotherGoodClass"));
    assertNull(typeOracle.findType("test.refresh.with.errors.BadClass"));
    assertNull(typeOracle.findType("test.refresh.with.errors.ClassThatWillGoBad"));
    assertNull(typeOracle.findType("test.refresh.with.errors.GoodClass"));
  }

  public void testSyntaxErrors() throws TypeOracleException {
    resources.add(CU_Object);
    resources.add(CU_HasSyntaxErrors);
    buildTypeOracle();

    assertNull(typeOracle.findType(CU_HasSyntaxErrors.getTypeName()));
    assertNotNull(typeOracle.findType(CU_Object.getTypeName()));
    assertEquals(1, typeOracle.getTypes().length);
  }

  public void testUnresolvedSymbols() throws TypeOracleException {
    resources.add(CU_Object);
    resources.add(CU_HasUnresolvedSymbols);
    resources.add(CU_RefsInfectedCompilationUnit);
    buildTypeOracle();

    assertNull(typeOracle.findType(CU_HasUnresolvedSymbols.getTypeName()));
    assertNull(typeOracle.findType(CU_RefsInfectedCompilationUnit.getTypeName()));
    assertNotNull(typeOracle.findType(CU_Object.getTypeName()));
    assertEquals(1, typeOracle.getTypes().length);
  }

  public void testJava8InterfaceExclusions() throws TypeOracleException {
    String java8Interface = Joiner.on("\n").join(
        "package test.java8;",
        "interface Java8Interface {",
        "  Object field = new Object();",
        "  final int constant = 1;",
        "  void m();",
        "  default void n() {};",
        "  static void o() {};",
        "}");
    addResource("test.java8.Java8Interface", java8Interface);
    resources.add(CU_Object);
    buildTypeOracle();

    assertEquals(1, typeOracle.findType("test.java8.Java8Interface").getMethods().length);
    assertEquals("m", typeOracle.findType("test.java8.Java8Interface").getMethods()[0].getName());
    assertNotNull(typeOracle.findType(CU_Object.getTypeName()));
    assertEquals(2, typeOracle.getTypes().length);
  }

  @Override
  protected void buildTypeOracle() throws TypeOracleException {
    typeOracle = TypeOracleTestingUtils.buildTypeOracle(createTreeLogger(),
        resources);
    checkTypes(typeOracle.getTypes());
  }
}
