/*
 * 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.testing.impl.StaticJavaResource;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.ast.JsContext;
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 JsniMethodCollector}.
 */
public class JsniMethodCollectorTest 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() {
    StringBuilder code = new StringBuilder();
    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.isError());
    assertEquals(
        "Referencing method 'Foo.m(Ljava/lang/String)': unable to resolve method in class 'Foo'",
        problem.getMessage());
  }

  public void testMalformedJsniRefPosition() {
    StringBuilder code = new StringBuilder();
    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() {
    StringBuilder code = new StringBuilder();
    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() {
    StringBuilder code = new StringBuilder();
    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 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;
  }
}
