/*
 * Copyright 2011 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.uibinder.rebind;

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;


import org.xml.sax.SAXParseException;


/**
 * Tests UiBinderWriter validation of UiRender getters and render method.
 */
public class UiRendererValidationTest extends AbstractUiBinderWriterTest {

  private static String UI_XML = "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>"
      + "<ui:style field='styleField'>.foo {color:black;}</ui:style>"
      + "<ui:with field='withField' />"
      + "  <div ui:field='root'>"
      + "    <span ui:field='someField'><ui:text from='{withField.toString}'/></span>"
      + "  </div>"
      + "</ui:UiBinder>";

  private static String UI_XML_TYPED_WITH = "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>"
    + "<ui:with field='withField' type='foo.Foo' />"
    + "  <div ui:field='root'>"
    + "    <span ui:field='someField'><ui:text from='{withField.toString}'/></span>"
    + "  </div>"
    + "</ui:UiBinder>";

  private StringBuffer declaredMethods = new StringBuffer();

  public void testAGoodUiRendererInterface() throws UnableToCompleteException, SAXParseException {
    declaredMethods.append("    public void render(SafeHtmlBuilder sb, foo.Foo withField);");
    declaredMethods.append("    public DivElement getRoot(Element foo);");
    declaredMethods.append("    public SpanElement getSomeField(Element bar);");
    declaredMethods.append("    public UiStyle getStyleField();");
    init(UI_XML, generateRendererResource(declaredMethods));
    writer.parseDocument(doc, printWriter);
  }

  public void testGetterBadParameterType() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public DivElement getRoot(String bar);");
    init(UI_XML, generateRendererResource(declaredMethods));

    assertParseFailure("Expected failure due to getter parameter not of type Element.",
        "Getter getRoot must have exactly one parameter of type assignable to "
            + "com.google.gwt.dom.client.Element in renderer.OwnerClass.Renderer");
  }

  public void testGetterParameterAssignableToElement()
      throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public DivElement getRoot(DivElement bar);");
    init(UI_XML, generateRendererResource(declaredMethods));

    writer.parseDocument(doc, printWriter);
  }

  public void testGetterNoParameters() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public DivElement getRoot();");
    init(UI_XML, generateRendererResource(declaredMethods));

    assertParseFailure("Expected failure due to getter with no parameters.",
        "Field getter getRoot must have exactly one parameter in renderer.OwnerClass.Renderer");
  }

  public void testStyleGetterWithParameter() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public UiStyle getStyleField(DivElement bar);");
    init(UI_XML, generateRendererResource(declaredMethods));

    assertParseFailure("Expected failure due to style getter with a parameter.",
        "Style getter getStyleField must have no parameters in renderer.OwnerClass.Renderer");
  }

  public void testGetterTooManyParameters() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public DivElement getRoot(Element parent, Integer i);");
    init(UI_XML, generateRendererResource(declaredMethods));

    assertParseFailure("Expected failure due to bad getter signature.",
        "Field getter getRoot must have exactly one parameter in renderer.OwnerClass.Renderer");
  }

  public void testGetterUnknownField() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public DivElement getQuux(Element parent);");
    init(UI_XML, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to getter for an unexpected field name.",
        "getQuux does not match a \"ui:field='quux'\" declaration in renderer.OwnerClass.Renderer,"
            + " or 'quux' refers to something other than a ui:style or an HTML element in"
            + " the template");
  }

  public void testRenderBadReturnType() throws SAXParseException, UnableToCompleteException {
    declaredMethods.append("    public String render(SafeHtmlBuilder sb, foo.Foo withField);");
    init(UI_XML, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to bad render() return type.",
        "renderer.OwnerClass.Renderer#render(SafeHtmlBuilder ...) does not return void");
  }

  public void testRenderExtraParametersOk() throws SAXParseException, UnableToCompleteException {
    declaredMethods.append("    public void render("
        + "SafeHtmlBuilder sb, foo.Foo withField, foo.Foo withUnknownField);");
    init(UI_XML, generateRendererResource(declaredMethods));
    writer.parseDocument(doc, printWriter);
  }

  public void testRenderMethodRepeated() throws SAXParseException, UnableToCompleteException {
    declaredMethods.append("    public void render(SafeHtmlBuilder sb, foo.Foo withField);");
    declaredMethods.append("    public void render(SafeHtmlBuilder sb);");
    init(UI_XML, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to more than one render method.",
        "renderer.OwnerClass.Renderer declares more than one method named render");
  }

  public void testRenderMissing() throws SAXParseException, UnableToCompleteException {
    // No render method here
    init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to missing render method.",
        "renderer.OwnerClass.Renderer does not declare a render(SafeHtmlBuilder ...) method");
  }

  public void testRenderNoParameters() throws SAXParseException, UnableToCompleteException {
    declaredMethods.append("    public void render();");
    init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to render with no parameters.",
        "renderer.OwnerClass.Renderer does not declare a render(SafeHtmlBuilder ...) method");
  }

  public void testRenderNoParametersRepeated() throws SAXParseException, UnableToCompleteException {
    declaredMethods.append("    public void render(SafeHtmlBuilder sb, foo.Foo withField);");
    declaredMethods.append("    public void render();");
    init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to render method repeated.",
        "renderer.OwnerClass.Renderer declares more than one method named render");
  }

  public void testUnknownMethodDeclaration() throws SAXParseException, UnableToCompleteException {
    initGetterTest();
    declaredMethods.append("    public void quux();");
    init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
    assertParseFailure("Expected failure due to unexpected method.",
        "Unexpected method \"quux\" found in renderer.OwnerClass.Renderer");
  }

  private void assertParseFailure(String message, String expectedMessage) {
    try {
      writer.parseDocument(doc, printWriter);
      fail(message);
    } catch (UnableToCompleteException e) {
      if (expectedMessage != null) {
        assertEquals(expectedMessage, logger.died);
      } else {
        fail("No message was received. " + message);
      }
    }
  }

  private MockJavaResource generateRendererResource(final StringBuffer declarations) {
    return new MockJavaResource("renderer.OwnerClass") {
      @Override
      public CharSequence getContent() {
        StringBuffer code = new StringBuffer();
        code.append("package renderer;\n");
        code.append("import com.google.gwt.safehtml.shared.SafeHtmlBuilder;\n");
        code.append("import com.google.gwt.uibinder.client.UiRenderer;\n");
        code.append("import com.google.gwt.dom.client.DivElement;\n");
        code.append("import com.google.gwt.dom.client.Element;\n");
        code.append("import com.google.gwt.dom.client.SpanElement;\n");
        code.append("import foo.Foo;\n");
        code.append("import foo.UiStyle;\n");
        code.append("public class OwnerClass {");
        code.append("  public interface Renderer");
        code.append("      extends UiRenderer {");
        code.append(declarations);
        code.append("  }");
        code.append("}");
        return code;
      }
    };
  }

  private void initGetterTest() {
    // Required, not part of test
    declaredMethods.append("    public void render(SafeHtmlBuilder sb, foo.Foo withField);");
  }
}
