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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.javac.CompilationUnit.GeneratedClassnameFinder;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

import junit.framework.TestCase;

import java.util.List;

/**
 * Test-cases to check that we indeed obtain the correct list of nested types
 * with generated classNames by examining bytecodes using ASM.
 * 
 */
public class GeneratedClassnameFinderTest extends TestCase {
  enum EnumClass {
    A, B, C,
  }

  static class MainClass {
    static class NestedClass {
      void foo() {
        TestInterface c = new TestInterface() {
          public void foo() {
          }
        };
        EnumClass et = EnumClass.A;
        switch (et) {
          case A:
            break;
        }
        TestInterface d = new TestInterface() {
          public void foo() {
          }
        };
      }
    }

    void foo() {
      TestInterface a = new TestInterface() {
        public void foo() {
        }
      };
      EnumClass et = EnumClass.A;
      switch (et) {
        case A:
          break;
      }
      TestInterface b = new TestInterface() {
        public void foo() {
        }
      };
    }
  }
  interface TestInterface {
    void foo();
  }

  static final TreeLogger logger = new PrintWriterTreeLogger();

  public void test() {
    String mainClassName = this.getClass().getName().replace('.', '/');
    assertEquals(
        4,
        new GeneratedClassnameFinder(logger, mainClassName).getClassNames().size());
    assertEquals(0, new GeneratedClassnameFinder(logger, mainClassName
        + "$EnumClass").getClassNames().size());
    assertEquals(0, new GeneratedClassnameFinder(logger, mainClassName
        + "$TestInterface").getClassNames().size());
    assertEquals(4, new GeneratedClassnameFinder(logger, mainClassName
        + "$MainClass").getClassNames().size());
    assertEquals(2, new GeneratedClassnameFinder(logger, mainClassName
        + "$MainClass$NestedClass").getClassNames().size());
  }

  public void testAnonymous() {
    assertEquals(1, new AnonymousTester().getGeneratedClasses().size());
  }

  public void testEnum() {
    assertEquals(0, new EnumTester().getGeneratedClasses().size());
  }

  public void testJavacWeirdness() {
    List<String> classNames = new JavacWeirdnessTester().getGeneratedClasses();
    assertEquals(3, classNames.size());
    assertTrue(classNames.get(0) + " should not contain Foo",
        classNames.get(0).indexOf("Foo") == -1);
    assertTrue(classNames.get(1) + " should contain Foo",
        classNames.get(1).indexOf("Foo") != -1);
    assertTrue(classNames.get(2) + " should contain Foo",
        classNames.get(2).indexOf("Foo") != -1);
  }

  public void testNamedLocal() {
    assertEquals(2, new NamedLocalTester().getGeneratedClasses().size());
  }

  public void testNested() {
    assertEquals(2, new NestedTester().getGeneratedClasses().size());
  }

  public void testStatic() {
    assertEquals(0, new StaticTester().getGeneratedClasses().size());
  }

  public void testTopLevel() {
    assertEquals(1, new TopLevelTester().getGeneratedClasses().size());
  }

}

/**
 * For testing a class containing an anonymous inner class.
 */
class AnonymousTester {
  interface TestInterface {
    void foo();
  }

  void foo() {
    TestInterface a = new TestInterface() {
      public void foo() {
      }
    };
    a.foo();
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }
}

/**
 * For testing a class with an Enum (for which javac generates a synthetic
 * class).
 */
class EnumTester {
  enum EnumClass {
    A, B, C,
  }

  void foo() {
    EnumClass et = EnumClass.A;
    switch (et) {
      case A:
        break;
    }
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }
}

/**
 * Javac generates weird code for the following class. It passes a synthetic
 * class ...Tester$1 as a first parameter to constructors of Fuji and Granny.
 * Normally, it generates the synthetic class, but in this case, it decides not
 * to generate the class. However, the bytecode still has reference to the
 * synthetic class -- it just passes null for the synthetic class.
 * 
 * This code also tests for an anonymous class extending a named local class.
 */
class JavacWeirdnessTester {
  private abstract static class Apple implements Fruit {
  }

  private static interface Fruit {
  }

  private static class Fuji extends Apple {
  }

  private static class Granny extends Apple {
  }

  private static volatile boolean TRUE = true;

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }

  private void assertEquals(Object a, Object b) {
  }

  private void testArrayStore() {
    Apple[] apple = TRUE ? new Granny[3] : new Apple[3];
    Apple g = TRUE ? (Apple) new Granny() : (Apple) new Fuji();
    Apple a = apple[0] = g;
    assertEquals(g, a);
  }

  private void testDeadTypes() {
    if (false) {
      new Object() {
      }.toString();

      class Foo {
        void a() {
        }
      }
      new Foo().a();
    }
  }

  private void testLocalClasses() {
    class Foo {
      public Foo(int j) {
        assertEquals(1, j);
      };
    }
    final int i;
    new Foo(i = 1) {
      {
        assertEquals(1, i);
      }
    };
    assertEquals(1, i);
  }

  private void testReturnStatementInCtor() {
    class Foo {
      int i;

      Foo(int i) {
        this.i = i;
        if (i == 0) {
          return;
        } else if (i == 1) {
          return;
        }
        return;
      }
    }
    assertEquals(new Foo(0).i, 0);
  }
}

/**
 * For testing a class with a generated name like $1Foo.
 */
class NamedLocalTester {
  void foo1() {
    if (false) {
      class Foo {
        void foo() {
        }
      }
      new Foo().foo();
    }
  }

  void foo2() {
    class Foo {
      void foo() {
      }
    }
    new Foo().foo();
  }

  void foo3() {
    class Foo {
      void foo() {
      }
    }
    new Foo().foo();
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }
}

/**
 * For testing that nested classes are examined recursively for classes with
 * generated names.
 */
class NestedTester {
  class MainClass {
    class NestedClass {
      void foo() {
        class Foo {
          void bar() {
          }
        }
        new Foo().bar();
      }
    }

    void foo() {
      class Foo {
        void bar() {
        }
      }
      new Foo().bar();
    }
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }
}

/**
 * For testing classes with private static members (javac generates a synthetic
 * class here but the jdt does not).
 */
class StaticTester {
  private abstract static class Apple implements Fruit {
  }

  private static interface Fruit {
    void bar();
  }

  private static class Fuji extends Apple {
    public void bar() {
    }
  }

  private static class Granny extends Apple {
    public void bar() {
    }
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }

}

/**
 * For testing that a class with a generated name inside another top-level class
 * is found.
 */
class TopLevelTester {
  public void foo() {
    GeneratedClassnameFinderTest.TestInterface a = new GeneratedClassnameFinderTest.TestInterface() {
      public void foo() {
      }
    };
  }

  List<String> getGeneratedClasses() {
    return (new GeneratedClassnameFinder(GeneratedClassnameFinderTest.logger,
        this.getClass().getName().replace('.', '/'))).getClassNames();
  }
}
