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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.rebind.MortalLogger;
import com.google.gwt.uibinder.rebind.UiBinderContext;
import com.google.gwt.uibinder.test.UiJavaResources;

import junit.framework.TestCase;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Tests for the owner class descriptor.
 */
public class OwnerClassTest extends TestCase {

  private static TreeLogger createCompileLogger() {
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
        System.err, true));
    logger.setMaxDetail(TreeLogger.ERROR);
    return logger;
  }

  private TypeOracle types;
  private JClassType labelType;
  private JClassType buttonType;
  private JClassType clickEventType;
  private JClassType mouseOverEventType;
  private UiBinderContext uiBinderCtx;

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    CompilationState state = CompilationStateBuilder.buildFrom(
        createCompileLogger(), new CompilerContext(), getJavaResources());
    types = state.getTypeOracle();
    uiBinderCtx = new UiBinderContext();
    labelType = types.findType("com.google.gwt.user.client.ui.Label");
    buttonType = types.findType("com.google.gwt.user.client.ui.Button");
    clickEventType = types.findType("com.google.gwt.event.dom.client.ClickEvent");
    mouseOverEventType = types.findType("com.google.gwt.event.dom.client.MouseOverEvent");
  }

  private Set<Resource> getJavaResources() {
    MockJavaResource[] javaFiles = {
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.EmptyOwnerClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("public class EmptyOwnerClass {\n");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.BadUiFactoryClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("public class BadUiFactoryClass {\n");
            code.append("  @UiFactory int thisShouldntWork() { return 0; }\n");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.UiFieldsClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.user.client.ui.Button;\n");
            code.append("import com.google.gwt.user.client.ui.Label;\n");
            code.append("import com.google.gwt.uibinder.client.UiField;\n");
            code.append("public class UiFieldsClass {\n");
            code.append("  @UiField Label label1;");
            code.append("  @UiField(provided=true) Button button1;");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.UiHandlersClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.event.dom.client.ClickEvent;\n");
            code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n");
            code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
            code.append("public class UiHandlersClass {\n");
            code.append("  @UiHandler(\"myField\") void onMyFieldClicked(ClickEvent ev) {}");
            code.append("  @UiHandler( {\"myField\", \"myOtherField\"}) void onMouseOver(MouseOverEvent ev){}");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.BadUiFieldsClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiField;\n");
            code.append("public class BadUiFieldsClass {\n");
            code.append("  @UiField int thisShouldntWork;");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.UiFactoryClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("import com.google.gwt.user.client.ui.Label;\n");
            code.append("public class UiFactoryClass {");
            code.append("  @UiFactory");
            code.append("  Label createLabel() { return null; }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource("com.google.gwt.uibinder.rebind.model.Abstract") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("public class Abstract<T> {");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("public class WildcardWidgetFactory {");
            code.append("  @UiFactory");
            code.append("  Abstract<?> createOne() { return null; }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("public class ParamterizedWidgetFactory {");
            code.append("  @UiFactory");
            code.append("  Abstract<String> createOne() { return null; }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.TooManyGenerics") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("public class TooManyGenerics {");
            code.append("  @UiFactory");
            code.append("  Abstract<?> createSomething() { return null; }");
            code.append("  @UiFactory");
            code.append("  Abstract<String> createStringThing() { return null; }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("import com.google.gwt.user.client.ui.Label;\n");
            code.append("public class DuplicateUiFactoryClass {");
            code.append("  @UiFactory");
            code.append("  Label labelFactory1() { return null; }");
            code.append("  @UiFactory");
            code.append("  Label labelFactory2() { return null; }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.ParentUiBinderClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n");
            code.append("import com.google.gwt.uibinder.client.UiField;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
            code.append("import com.google.gwt.user.client.ui.Label;\n");
            code.append("public class ParentUiBinderClass {");
            code.append("  @UiField Label label1;");
            code.append("  @UiFactory Label createLabel() { return null; }");
            code.append("  @UiHandler(\"label1\")");
            code.append("  void onLabelMouseOver(MouseOverEvent e) { }");
            code.append("}\n");
            return code;
          }
        },
        new MockJavaResource(
            "com.google.gwt.uibinder.rebind.model.ChildUiBinderClass") {
          @Override
          public CharSequence getContent() {
            StringBuffer code = new StringBuffer();
            code.append("package com.google.gwt.uibinder.rebind.model;\n");
            code.append("import com.google.gwt.event.dom.client.ClickEvent;\n");
            code.append("import com.google.gwt.uibinder.client.UiField;\n");
            code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
            code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
            code.append("import com.google.gwt.user.client.ui.Button;\n");
            code.append("public class ChildUiBinderClass extends ParentUiBinderClass {");
            code.append("  @UiField(provided = true) Button button1;");
            code.append("  @UiFactory Button createButton() { return null; }");
            code.append("  @UiHandler(\"button1\")");
            code.append("  void onButtonClicked(ClickEvent e) { }");
            code.append("}\n");
            return code;
          }
        },};

    Set<Resource> rtn = new HashSet<Resource>(UiJavaResources.getUiResources());
    rtn.addAll(Arrays.asList(javaFiles));
    return rtn;
  }

  @SuppressWarnings("deprecation")
  public void testOwnerClass_empty() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.EmptyOwnerClass");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    assertNull(ownerClass.getUiFactoryMethod(labelType));
    assertNull(ownerClass.getUiField("fieldName"));
    assertNull(ownerClass.getUiFieldForType(labelType));
    assertTrue(ownerClass.getUiFields().isEmpty());
    assertTrue(ownerClass.getUiHandlers().isEmpty());
  }

  public void testOwnerClass_uiFactory() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFactoryClass");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
    assertNotNull(uiFactoryMethod);
    assertEquals("createLabel", uiFactoryMethod.getName());
    assertEquals(labelType, uiFactoryMethod.getReturnType());
    JParameter[] parameters = uiFactoryMethod.getParameters();
    assertNotNull(parameters);
    assertEquals(0, parameters.length);
  }

  public void testParameterizedWidgets() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory");
    JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    JMethod expected = ownerType.findMethod("createOne", new JType[] {});
    JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType);

    assertEquals(expected, uiFactoryMethod);
  }

  public void testWildcardWidgets() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory");
    JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    JMethod expected = ownerType.findMethod("createOne", new JType[] {});
    JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType);

    assertEquals(expected, uiFactoryMethod);
  }

  public void testHowSuckyWeReallyAreWithGenerics() {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.TooManyGenerics");

    try {
      new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
      fail();
    } catch (UnableToCompleteException e) {
      /* pass */
    }
  }

  public void testOwnerClass_uiFactoryBadType() {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFactoryClass");
    try {
      new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
      fail("Expected exception not thrown.");
    } catch (UnableToCompleteException utce) {
      // Expected
    }
  }

  public void testOwnerClass_uiFactoryDuplicateType() {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass");
    try {
      new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
      fail("Expected exception not thrown.");
    } catch (UnableToCompleteException utce) {
      // Expected
    }
  }

  @SuppressWarnings("deprecation")
  public void testOwnerClass_uiFields() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFieldsClass");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    OwnerField labelField = ownerClass.getUiField("label1");
    OwnerField labelField2 = ownerClass.getUiFieldForType(labelType);
    assertNotNull(labelField);
    assertNotNull(labelField2);
    assertEquals(labelField, labelField2);
    assertFalse(labelField.isProvided());
    assertEquals(labelType, labelField.getType().getRawType());
    assertEquals("label1", labelField.getName());

    OwnerField buttonField = ownerClass.getUiField("button1");
    OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType);
    assertNotNull(buttonField);
    assertNotNull(buttonField2);
    assertEquals(buttonField, buttonField2);
    assertTrue(buttonField.isProvided());
    assertEquals(buttonType, buttonField.getType().getRawType());
    assertEquals("button1", buttonField.getName());

    Collection<OwnerField> uiFields = ownerClass.getUiFields();
    Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields);
    Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>();
    expectedFieldSet.add(labelField);
    expectedFieldSet.add(buttonField);
    assertEquals(expectedFieldSet, uiFieldSet);
  }

  public void testOwnerClass_uiFieldsBadType() {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFieldsClass");
    try {
      new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
      fail("Expected exception not thrown.");
    } catch (UnableToCompleteException utce) {
      // Expected
    }
  }

  public void testOwnerClass_uiHandlers() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiHandlersClass");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    // Assert the two expected handlers are there
    List<JMethod> uiHandlers = ownerClass.getUiHandlers();
    assertEquals(2, uiHandlers.size());
    JMethod clickMethod = null, mouseOverMethod = null;

    // Don't care about ordering
    for (JMethod method : uiHandlers) {
      if (method.getName().equals("onMyFieldClicked")) {
        clickMethod = method;
      } else if (method.getName().equals("onMouseOver")) {
        mouseOverMethod = method;
      }
    }

    assertNotNull(clickMethod);
    assertNotNull(mouseOverMethod);

    // Check the click handler
    JParameter[] clickParams = clickMethod.getParameters();
    assertEquals(1, clickParams.length);
    assertEquals(clickEventType, clickParams[0].getType());
    assertTrue(clickMethod.isAnnotationPresent(UiHandler.class));
    UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class);
    String[] clickFields = clickAnnotation.value();
    assertEquals(1, clickFields.length);
    assertEquals("myField", clickFields[0]);

    // Check the mouse over handler
    JParameter[] mouseOverParams = mouseOverMethod.getParameters();
    assertEquals(1, mouseOverParams.length);
    assertEquals(mouseOverEventType, mouseOverParams[0].getType());
    assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class));
    UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class);
    String[] mouseOverFields = mouseOverAnnotation.value();
    assertEquals(2, mouseOverFields.length);
    assertEquals("myField", mouseOverFields[0]);
    assertEquals("myOtherField", mouseOverFields[1]);
  }

  @SuppressWarnings("deprecation")
  public void testOwnerClass_withParent() throws UnableToCompleteException {
    JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ChildUiBinderClass");
    OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
        uiBinderCtx);

    // Test fields
    OwnerField labelField = ownerClass.getUiField("label1");
    OwnerField labelField2 = ownerClass.getUiFieldForType(labelType);
    assertNotNull(labelField);
    assertNotNull(labelField2);
    assertEquals(labelField, labelField2);
    assertFalse(labelField.isProvided());
    assertEquals(labelType, labelField.getType().getRawType());
    assertEquals("label1", labelField.getName());

    OwnerField buttonField = ownerClass.getUiField("button1");
    OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType);
    assertNotNull(buttonField);
    assertNotNull(buttonField2);
    assertEquals(buttonField, buttonField2);
    assertTrue(buttonField.isProvided());
    assertEquals(buttonType, buttonField.getType().getRawType());
    assertEquals("button1", buttonField.getName());

    Collection<OwnerField> uiFields = ownerClass.getUiFields();
    Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields);
    Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>();
    expectedFieldSet.add(labelField);
    expectedFieldSet.add(buttonField);
    assertEquals(expectedFieldSet, uiFieldSet);

    // Test factories
    JMethod labelFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
    assertNotNull(labelFactoryMethod);
    assertEquals("createLabel", labelFactoryMethod.getName());
    assertEquals(labelType, labelFactoryMethod.getReturnType());
    JParameter[] labelParams = labelFactoryMethod.getParameters();
    assertNotNull(labelParams);
    assertEquals(0, labelParams.length);

    JMethod buttonFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
    assertNotNull(buttonFactoryMethod);
    assertEquals("createLabel", buttonFactoryMethod.getName());
    assertEquals(labelType, buttonFactoryMethod.getReturnType());
    JParameter[] buttonParams = buttonFactoryMethod.getParameters();
    assertNotNull(buttonParams);
    assertEquals(0, buttonParams.length);

    // Test handlers
    List<JMethod> uiHandlers = ownerClass.getUiHandlers();
    assertEquals(2, uiHandlers.size());
    JMethod clickMethod = null, mouseOverMethod = null;

    for (JMethod method : uiHandlers) {
      if (method.getName().equals("onButtonClicked")) {
        clickMethod = method;
      } else if (method.getName().equals("onLabelMouseOver")) {
        mouseOverMethod = method;
      }
    }

    assertNotNull(clickMethod);
    assertNotNull(mouseOverMethod);

    JParameter[] clickParams = clickMethod.getParameters();
    assertEquals(1, clickParams.length);
    assertEquals(clickEventType, clickParams[0].getType());
    assertTrue(clickMethod.isAnnotationPresent(UiHandler.class));
    UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class);
    String[] clickFields = clickAnnotation.value();
    assertEquals(1, clickFields.length);
    assertEquals("button1", clickFields[0]);

    JParameter[] mouseOverParams = mouseOverMethod.getParameters();
    assertEquals(1, mouseOverParams.length);
    assertEquals(mouseOverEventType, mouseOverParams[0].getType());
    assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class));
    UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class);
    String[] mouseOverFields = mouseOverAnnotation.value();
    assertEquals(1, mouseOverFields.length);
    assertEquals("label1", mouseOverFields[0]);
  }
}
