/*
 * 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.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.javac.JdtCompiler.AdditionalTypeProviderDelegate;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.javac.testing.impl.MockResourceOracle;
import com.google.gwt.dev.jjs.JavaAstConstructor;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.util.Strings;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

import junit.framework.TestCase;

import java.util.Set;
import java.util.TreeSet;

/**
 * A useful base class for tests that build JJS ASTs.
 */
public abstract class JJSTestBase extends TestCase {

  public static final String MAIN_METHOD_NAME = "onModuleLoad";

  /**
   * Finds a field with a type.
   */
  public static JField findField(JDeclaredType type, String fieldName) {
    for (JField field : type.getFields()) {
      if (field.getName().equals(fieldName)) {
        return field;
      }
    }
    return null;
  }

  /**
   * Finds a field by name, e.g. <code>Foo.field</code>.
   */
  public static JField findField(JProgram program, String qualifiedFieldName) {
    int pos = qualifiedFieldName.lastIndexOf('.');
    assertTrue(pos > 0);
    String typeName = qualifiedFieldName.substring(0, pos);
    String fieldName = qualifiedFieldName.substring(pos + 1);
    JDeclaredType type = findType(program, typeName);
    JField field = findField(type, fieldName);
    return field;
  }

  /**
   * Find a local variable declared within a JMethod.
   */
  public static JLocal findLocal(JMethod method, final String localName) {
    class LocalVisitor extends JVisitor {
      JLocal found;

      @Override
      public void endVisit(JLocal x, Context ctx) {
        if (x.getName().equals(localName)) {
          found = x;
        }
      }
    }
    LocalVisitor v = new LocalVisitor();
    v.accept(method);
    return v.found;
  }

  public static JMethod findMainMethod(JProgram program) {
    return findMethod(program, MAIN_METHOD_NAME);
  }

  public static JMethod findMethod(JDeclaredType type, String methodName) {
    for (JMethod method : type.getMethods()) {
      if (method.getName().equals(methodName)) {
        return method;
      }
    }

    return null;
  }

  public static JMethod findMethod(JProgram program, String methodName) {
    JDeclaredType mainType = program.getFromTypeMap("test.EntryPoint");
    return findMethod(mainType, methodName);
  }

  public static JMethod findQualifiedMethod(JProgram program, String methodName) {
    int pos = methodName.lastIndexOf('.');
    assertTrue(pos > 0);
    String typeName = methodName.substring(0, pos);
    String unqualMethodName = methodName.substring(pos + 1);
    JDeclaredType type = findType(program, typeName);
    return findMethod(type, unqualMethodName);
  }

  /**
   * Finds a type by name. The type name may be short, e.g. <code>"Foo"</code>,
   * or fully-qualified, e.g. <code>"com.google.example.Foo"</code>. If a short
   * name is used, it must be unambiguous.
   */
  public static JDeclaredType findType(JProgram program, String typeName) {
    JDeclaredType type = program.getFromTypeMap(typeName);
    if (type == null && typeName.indexOf('.') < 0) {
      // Do a slow lookup by short name.
      for (JDeclaredType checkType : program.getDeclaredTypes()) {
        if (checkType.getShortName().equals(typeName)) {
          if (type == null) {
            type = checkType;
          } else {
            fail("Ambiguous type reference '" + typeName + "' might be '"
                + type.getName() + "' or '" + checkType.getName()
                + "' (possibly more matches)");
          }
        }
      }
    }
    return type;
  }

  public static String getMainMethodSource(JProgram program) {
    JMethod mainMethod = findMainMethod(program);
    return mainMethod.getBody().toSource();
  }

  /**
   * Tweak this if you want to see the log output.
   */
  private static TreeLogger createTreeLogger() {
    boolean reallyLog = true;
    if (reallyLog) {
      AbstractTreeLogger logger = new PrintWriterTreeLogger();
      logger.setMaxDetail(TreeLogger.WARN);
      return logger;
    }
    return TreeLogger.NULL;
  }

  protected TreeLogger logger = createTreeLogger();

  protected final MockResourceOracle sourceOracle = new MockResourceOracle();

  private final Set<String> snippetClassDecls = new TreeSet<String>();

  private final Set<String> snippetImports = new TreeSet<String>();

  public JJSTestBase() {
    sourceOracle.add(JavaAstConstructor.getCompilerTypes());
  }

  /**
   * Adds a snippet of code, for example a field declaration, to the class that
   * encloses the snippet subsequently passed to
   * {@link #compileSnippet(String, String)}.
   */
  protected void addSnippetClassDecl(String...decl) {
    snippetClassDecls.add(Strings.join(decl, "\n"));
  }

  /**
   * Adds an import statement for any code subsequently passed to
   * {@link #compileSnippet(String, String)}.
   */
  protected void addSnippetImport(String typeName) {
    snippetImports.add(typeName);
  }

  /**
   * Returns the program that results from compiling the specified code snippet
   * as the body of an entry point method.
   * 
   * @param returnType the return type of the method to compile; use "void" if
   *          the code snippet has no return statement
   * @param codeSnippet the body of the entry method
   */
  protected JProgram compileSnippet(final String returnType,
      final String codeSnippet) throws UnableToCompleteException {
    return compileSnippet(returnType, "", codeSnippet);
  }

  /**
   * Returns the program that results from compiling the specified code snippet
   * as the body of an entry point method.
   * 
   * @param returnType the return type of the method to compile; use "void" if
   *          the code snippet has no return statement
   * @param params the parameter list of the method to compile
   * @param codeSnippet the body of the entry method
   */
  protected JProgram compileSnippet(final String returnType,
      final String params, final String codeSnippet)
      throws UnableToCompleteException {
    sourceOracle.addOrReplace(new MockJavaResource("test.EntryPoint") {
      @Override
      public CharSequence getContent() {
        StringBuffer code = new StringBuffer();
        code.append("package test;\n");
        for (String snippetImport : snippetImports) {
          code.append("import " + snippetImport + ";\n");
        }
        code.append("public class EntryPoint {\n");
        for (String snippetClassDecl : snippetClassDecls) {
          code.append(snippetClassDecl + ";\n");
        }
        code.append("  public static " + returnType + " onModuleLoad(" + params
            + ") {\n");
        code.append(codeSnippet);
        code.append("  }\n");
        code.append("}\n");
        return code;
      }
    });
    addBuiltinClasses(sourceOracle);
    boolean wasEnabled = GwtAstBuilder.ENABLED;
    try {
      GwtAstBuilder.ENABLED = true;
      CompilationState state = CompilationStateBuilder.buildFrom(logger,
          sourceOracle.getResources(), getAdditionalTypeProviderDelegate());
      JProgram program = JavaAstConstructor.construct(logger, state,
          "test.EntryPoint", "com.google.gwt.lang.Exceptions");
      return program;
    } finally {
      GwtAstBuilder.ENABLED = wasEnabled;
    }
  }

  protected void addBuiltinClasses(MockResourceOracle sourceOracle) {
    sourceOracle.addOrReplace(new MockJavaResource("java.lang.RuntimeException") {
      @Override
      public CharSequence getContent() {
        return "package java.lang;" +
          "public class RuntimeException extends Exception { }";
      }
    });

    sourceOracle.addOrReplace(new MockJavaResource("com.google.gwt.lang.Exceptions") {
      @Override
      public CharSequence getContent() {
        return "package com.google.gwt.lang;" +
          "public class Exceptions { static boolean throwAssertionError() { throw new RuntimeException(); } }";
      }
    });

    sourceOracle.addOrReplace(new MockJavaResource("java.lang.String") {
      @Override
      public CharSequence getContent() {
        return "package java.lang;" +
          "public class String {" +
          "  public int length() { return 0; }" +
          "  public char charAt(int pos) { return 0; }" +
          "}";
      }
    });
  }
  
  /**
   * Return an AdditionalTypeProviderDelegate that will be able to provide
   * new sources for unknown classnames. 
   */
  protected AdditionalTypeProviderDelegate getAdditionalTypeProviderDelegate() {
    return null;
  }
}
