/*
 * Copyright 2009 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.impl.StaticJavaResource;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsExpression;
import com.google.gwt.dev.js.ast.JsNameRef;
import com.google.gwt.dev.js.ast.JsVisitor;

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

import java.util.ArrayList;
import java.util.List;

/**
 * Tests {@link JsniCollector}.
 */
public class JsniCollectorTest extends CompilationStateTestBase {

  /**
   * TODO: currently JSNI does not parse character position. Turn this on (and
   * delete it, actually) when it does.
   */
  public static final boolean JSNI_PARSES_SOURCE_POSITION = false;

  public void testErrorPosition() {
    StringBuffer code = new StringBuffer();
    code.append("class Foo {\n");
    code.append("  native void m(Object o) /*-{\n");
    code.append("    o.@Foo::m(Ljava/lang/String);\n");
    code.append("  }-*/;\n");
    code.append("}\n");
    String source = code.toString();

    CategorizedProblem[] problems = getProblems("Foo", source);
    assertEquals(1, problems.length);
    CategorizedProblem problem = problems[0];
    if (JSNI_PARSES_SOURCE_POSITION) {
      assertEquals(source.indexOf('@'), problem.getSourceStart());
    }
    assertEquals(3, problem.getSourceLineNumber());
    assertTrue(problem.isWarning());
    assertEquals(
        "Referencing method 'Foo.m(Ljava/lang/String)': unable to resolve method, expect subsequent failures",
        problem.getMessage());
  }

  public void testMalformedJsniRefPosition() {
    StringBuffer code = new StringBuffer();
    code.append("class Foo {\n");
    code.append("  native void m() /*-{\n");
    code.append("    @Bar;\n");
    code.append("  }-*/;\n");
    code.append("}\n");
    String source = code.toString();
    CategorizedProblem[] problems = getProblems("Foo", source);
    assertEquals(1, problems.length);
    CategorizedProblem problem = problems[0];
    assertEquals(source.indexOf('@') + "Bar".length(), problem.getSourceStart());
    assertEquals(3, problem.getSourceLineNumber());
    assertTrue(problem.isError());
    assertEquals("Expected \":\" in JSNI reference\n>     @Bar;\n> --------^",
        problem.getMessage());
  }

  public void testMalformedJsniRefPositionWithExtraLines() {
    StringBuffer code = new StringBuffer();
    code.append("class Foo {\n");
    code.append("  native\nvoid\nm()\n\n\n/*-{\n\n");
    code.append("    @Bar;\n");
    code.append("  }-*/;\n");
    code.append("}\n");
    String source = code.toString();
    CategorizedProblem[] problems = getProblems("Foo", source);
    assertEquals(1, problems.length);
    CategorizedProblem problem = problems[0];
    assertEquals(source.indexOf('@') + "Bar".length(), problem.getSourceStart());
    assertEquals(9, problem.getSourceLineNumber());
    assertTrue(problem.isError());
    assertEquals("Expected \":\" in JSNI reference\n>     @Bar;\n> --------^",
        problem.getMessage());
  }

  public void testSourcePosition() {
    StringBuffer code = new StringBuffer();
    code.append("class Foo {\n");
    code.append("  native void m(Object o) /*-{\n");
    code.append("    o.@Foo::m(Ljava/lang/Object);\n");
    code.append("  }-*/;\n");
    code.append("}\n");
    String source = code.toString();

    List<JsNameRef> foundRefs = findJsniRefs("Foo", source);
    assertEquals(1, foundRefs.size());
    JsNameRef ref = foundRefs.get(0);
    SourceInfo info = ref.getSourceInfo();
    if (JSNI_PARSES_SOURCE_POSITION) {
      assertEquals(source.indexOf('@'), info.getStartPos());
    }
    assertEquals(3, info.getStartLine());
  }

  private List<JsNameRef> findJsniRefs(String typeName, final String source) {
    addGeneratedUnits(new StaticJavaResource(typeName, source));
    CompilationUnit unit = state.getCompilationUnitMap().get(typeName);
    assertNotNull(unit);
    List<JsniMethod> jsniMethods = unit.getJsniMethods();
    assertEquals(1, jsniMethods.size());
    JsniMethod jsniMethod = jsniMethods.get(0);
    final List<JsNameRef> foundRefs = new ArrayList<JsNameRef>();
    new JsVisitor() {
      @Override
      public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) {
        if (x.getIdent().startsWith("@")) {
          foundRefs.add(x);
        }
      }
    }.accept(jsniMethod.function());
    return foundRefs;
  }

  private CategorizedProblem[] getProblems(String typeName, String source) {
    addGeneratedUnits(new StaticJavaResource(typeName, source));
    CompilationUnit unit = state.getCompilationUnitMap().get(typeName);
    assertNotNull(unit);
    CategorizedProblem[] problems = unit.getProblems();
    return problems;
  }
}
