package ioc.specs

import com.example.TestInterface
import java.awt.Image
import java.beans.*
import java.lang.reflect.Method

import org.apache.tapestry5.beaneditor.DataType
import org.apache.tapestry5.beaneditor.Validate
import org.apache.tapestry5.ioc.annotations.Scope
import org.apache.tapestry5.ioc.internal.services.*
import org.apache.tapestry5.ioc.internal.util.Pair
import org.apache.tapestry5.ioc.internal.util.StringLongPair
import org.apache.tapestry5.ioc.services.ClassPropertyAdapter
import org.apache.tapestry5.ioc.services.PropertyAccess

import spock.lang.*

class ExceptionBean {

  boolean getFailure() {
    throw new RuntimeException("getFailure");
  }

  void setFailure(boolean b) {
    throw new RuntimeException("setFailure");
  }

  @Override
  String toString() {
    return "PropertyAccessImplSpecBean";
  }
}

class UglyBean {
}

class UglyBeanBeanInfo implements BeanInfo {

  BeanInfo[] getAdditionalBeanInfo() {
    return new BeanInfo[0];
  }

  BeanDescriptor getBeanDescriptor() {
    return null;
  }

  int getDefaultEventIndex() {
    return 0;
  }

  int getDefaultPropertyIndex() {
    return 0;
  }

  EventSetDescriptor[] getEventSetDescriptors() {
    return new EventSetDescriptor[0];
  }

  Image getIcon(int iconKind) {
    return null;
  }

  MethodDescriptor[] getMethodDescriptors() {
    return new MethodDescriptor[0];
  }

  PropertyDescriptor[] getPropertyDescriptors() {
    throw new RuntimeException("This is the UglyBean.");
  }

}

class ScalaBean {

  private String value;

  String getValue() {
    return value;
  }

  void setValue(String value) {
    this.value = value;
  }

  String value() {
    return value;
  }

  void value_$eq(String value) {
    this.value = value;
  }
}

class ScalaClass {

  private String value;

  String value() {
    return value;
  }

  void value_$eq(String value) {
    this.value = value;
  }
}

interface BeanInterface {

  String getValue();

  void setValue(String v);

  String getOtherValue();

  void setOtherValue(String v);

  int getIntValue(); // read-only
}

abstract class AbstractBean implements BeanInterface {
  // abstract class implements method from interface
  private String other;

  String getOtherValue() {
    return other;
  }

  void setOtherValue(String v) {
    other = v;
  }
}

class ConcreteBean extends AbstractBean {

  private String value;
  private int intValue;

  ConcreteBean(int intValue) {
    this.intValue = intValue;
  }

  String getValue() {
    return value;
  }

  void setValue(String v) {
    value = v;
  }

  int getIntValue() {
    return intValue;
  }
}

abstract class GenericBean<T> {

  public T value;
}

class GenericStringBean extends GenericBean<String> {
}

class PropertyAccessImplSpec extends Specification {

  @Shared
  PropertyAccess access = new PropertyAccessImpl()

  @Shared
  Random random = new Random()

  def "simple read access to a standard bean"() {
    Bean b = new Bean()
    int value = random.nextInt()

    when:

    b.value = value

    then:

    access.get(b, "value") == value
  }

  def "property name access is case insensitive"() {
    Bean b = new Bean()
    int value = random.nextInt()

    when:

    b.value = value

    then:

    access.get(b, "VaLUe") == value
  }

  def "simple write access to a standard bean"() {
    Bean b = new Bean()
    int value = random.nextInt()

    when:

    access.set(b, "value", value)

    then:

    b.value == value
  }

  def "missing properties are an exception"() {
    Bean b = new Bean()

    when:

    access.get(b, "zaphod")

    then:

    IllegalArgumentException e = thrown()

    e.message == "Class ${b.class.name} does not contain a property named 'zaphod'."
  }

  def "it is not possible to update a read-only property"() {
    Bean b = new Bean()

    when:

    access.set(b, "class", null)

    then:

    UnsupportedOperationException e = thrown()

    e.message == "Class ${b.class.name} does not provide a mutator ('setter') method for property 'class'."
  }

  def "it is not possible to read a write-only property"() {
    Bean b = new Bean()

    when:

    access.get(b, "writeOnly")

    then:

    UnsupportedOperationException e = thrown()

    e.message == "Class ${b.class.name} does not provide an accessor ('getter') method for property 'writeOnly'."
  }

  def "when a getter method throws an exception, the exception is wrapped and rethrown"() {

    ExceptionBean b = new ExceptionBean()

    when:

    access.get(b, "failure")

    then:

    RuntimeException e = thrown()

    e.message == "Error reading property 'failure' of ${b}: getFailure"
  }

  def "when a setter method throws an exception, the exception is wrapped and rethrown"() {
    ExceptionBean b = new ExceptionBean()

    when:

    access.set(b, "failure", false)

    then:

    RuntimeException e = thrown()

    e.message == "Error updating property 'failure' of ${b.class.name}: setFailure"
  }

  @Ignore
  def "exception throw when introspecting the class is wrapped and rethrown"() {

    // Due to Groovy, the exception gets thrown here, not inside
    // the access.get() method, thus @Ingore (for now)

    UglyBean b = new UglyBean()

    when:

    access.get(b, "google")

    then:

    RuntimeException e = thrown()

    e.message == "java.lang.RuntimeException: This is the UglyBean."
  }

  def "clearCache() wipes internal cache"() {
    when:

    ClassPropertyAdapter cpa1 = access.getAdapter Bean

    then:

    cpa1.is(access.getAdapter(Bean))


    when:

    access.clearCache()

    then:

    !cpa1.is(access.getAdapter(Bean))
  }

  def "ClassPropertyAdapter has a useful toString()"() {

    when:

    def cpa = access.getAdapter Bean

    then:

    cpa.toString() == "<ClassPropertyAdaptor ${Bean.class.name}: PI, class, readOnly, value, writeOnly>"
  }

  @Unroll
  def "expected properties for #beanClass.name property '#propertyName' are read=#read, update=#update, castRequired=#castRequired"() {

    when:

    def pa = getPropertyAdapter beanClass, propertyName

    then:

    pa.read == read
    pa.update == update
    pa.castRequired == castRequired
    pa.writeMethod == writeMethod
    pa.readMethod == readMethod

    where:

    beanClass | propertyName | read  | update | castRequired | writeMethodName | readMethodName
    Bean      | "readOnly"   | true  | false  | false        | null            | "getReadOnly"
    Bean      | "writeOnly"  | false | true   | false        | "setWriteOnly"  | null
    Bean      | "pi"         | true  | false  | false        | null            | null

    writeMethod = findMethod beanClass, writeMethodName
    readMethod = findMethod beanClass, readMethodName
  }

  def "PropertyAdapter for unknown property name is null"() {
    when:

    ClassPropertyAdapter cpa = access.getAdapter(Bean)

    then:

    cpa.getPropertyAdapter("google") == null
  }

  @Unroll
  def "PropertyAdapter.type for #beanClass.name property '#propertyName' is #type.name"() {

    ClassPropertyAdapter cpa = access.getAdapter(beanClass)

    when:

    def adapter = cpa.getPropertyAdapter(propertyName)

    then:

    adapter.type.is(type)

    where:

    beanClass | propertyName | type
    Bean      | "value"      | int
    Bean      | "readOnly"   | String
    Bean      | "writeOnly"  | boolean
  }

  def "ClassPropertyAdapter gives access to property names (in sorted order)"() {
    ClassPropertyAdapter cpa = access.getAdapter(Bean)

    expect:

    cpa.propertyNames == ["PI", "class", "readOnly", "value", "writeOnly"]
  }

  def "public static fields are treated as properties"() {
    when:

    def adapter = getPropertyAdapter Bean, "pi"

    then:

    adapter.get(null).is(Bean.PI)
  }

  def "public final static fields may not be updated"() {
    def adapter = getPropertyAdapter Bean, "pi"

    when:

    adapter.set(null, 3.0d)

    then:

    RuntimeException e = thrown()

    e.message.contains "final"
    e.message.contains "PI"
  }

  def "super interface methods are inherited by sub-interface"() {
    when:

    ClassPropertyAdapter cpa = access.getAdapter SubInterface

    then:

    cpa.propertyNames == ["grandParentProperty", "parentProperty", "subProperty"]
  }

  def "indexed properties are ignored"() {
    when:

    ClassPropertyAdapter cpa = access.getAdapter BeanWithIndexedProperty

    then:

    cpa.propertyNames == ["class", "primitiveProperty"]
  }

  def "getAnnotation from a bean property"() {
    AnnotatedBean b = new AnnotatedBean()

    when:

    def annotation = access.getAnnotation(b, "annotationOnRead", Scope)

    then:

    annotation.value() == "onread"
  }


  def "getAnnotation() when annotation is not present is null"() {

    when:

    def pa = getPropertyAdapter AnnotatedBean, "readWrite"

    then:

    pa.getAnnotation(Scope) == null
  }

  def "getAnnotation() with annotation on setter method"() {

    when:

    def pa = getPropertyAdapter AnnotatedBean, "annotationOnWrite"

    then:

    pa.getAnnotation(Scope).value() == "onwrite"
  }

  def "annotation on getter method overrides annotation on setter method"() {
    def pa = getPropertyAdapter AnnotatedBean, "annotationOnRead"

    when:

    Scope annotation = pa.getAnnotation(Scope)

    then:

    annotation.value() == "onread"
  }

  def "getAnnotation() works on read-only properties, skipping the missing setter method"() {

    when:

    def pa = getPropertyAdapter AnnotatedBean, "readOnly"

    then:

    pa.getAnnotation(Scope) == null
  }

  def "annotations directly on fields are located"() {
    when:

    def pa = access.getAdapter(Bean).getPropertyAdapter("value")

    then:

    pa.getAnnotation(DataType).value() == "fred"
  }

  @Issue("TAPESTY-2448")
  def "getAnnotation() will find annotations from an inherited field in a super-class"() {
    when:

    def pa = getPropertyAdapter AnnotatedBeanSubclass, "value"

    then:

    pa.getAnnotation(DataType).value() == "fred"
  }

  def "annotations on a getter or setter method override annotations on the field"() {
    when:

    def pa = getPropertyAdapter Bean, "value"

    then:

    pa.getAnnotation(Validate).value() == "getter-value-overrides"
  }

  def "PropertyAdapter.type understands (simple) generic signatures"() {
    def cpa1 = access.getAdapter(StringLongPair)

    when:

    def key = cpa1.getPropertyAdapter("key")

    then:

    key.type == String
    key.castRequired
    key.declaringClass == Pair

    when:

    def value = cpa1.getPropertyAdapter("value")

    then:

    value.type == Long
    value.castRequired

    when:

    def cpa2 = access.getAdapter(Pair)
    def pkey = cpa2.getPropertyAdapter("key")

    then:

    pkey.type == Object
    !pkey.castRequired

    when:

    def pvalue = cpa2.getPropertyAdapter("value")

    then:

    pvalue.type == Object
    !pvalue.castRequired
  }

  def "PropertyAdapter prefers JavaBeans property method names to Scala method names"() {
    when:

    def pa = getPropertyAdapter ScalaBean, "value"

    then:

    pa.readMethod.name == "getValue"
    pa.writeMethod.name == "setValue"
  }

  def "PropertyAdapter understands Scala accessor method naming"() {
    when:

    def pa = getPropertyAdapter ScalaClass, "value"

    then:

    pa.readMethod.name == "value"
    pa.writeMethod.name == 'value_$eq'
  }

  def "PropertyAccess exposes public fields as if they were properties"() {
    when:

    def pa = getPropertyAdapter PublicFieldBean, "value"

    then:

    pa.field
    pa.read
    pa.update

    when:

    PublicFieldBean bean = new PublicFieldBean()

    pa.set(bean, "fred")

    then:

    bean.value == "fred"

    when:

    bean.value = "barney"

    then:

    pa.get(bean) == "barney"
  }

  def "access to property is favored over public field when the names are the same"() {
    def bean = new ShadowedPublicFieldBean()

    when:

    def pa = getPropertyAdapter ShadowedPublicFieldBean, "value"

    then:

    !pa.field

    when:

    pa.set(bean, "fred")

    then:

    bean.@value == null

    when:

    bean.@value = "barney"
    bean.value = "wilma"

    then:

    pa.get(bean) == "wilma"
  }

  def "a property defined by an unimplemented inteface method of an abstract class is accessible"() {
    AbstractBean bean = new ConcreteBean(33)
    def ca = access.getAdapter(AbstractBean)

    when:

    def va = ca.getPropertyAdapter("value")

    then:

    !va.field

    when:

    va.set(bean, "hello")

    then:

    va.get(bean) == "hello"
    bean.value == "hello"

    when:

    def ova = ca.getPropertyAdapter("otherValue")

    then:

    !ova.field

    when:

    ova.set(bean, "other value")

    then:

    ova.get(bean) == "other value"
    bean.otherValue == "other value"

    when:

    def iva = ca.getPropertyAdapter("intvalue")

    then:

    iva.get(bean) == 33
    iva.read
    !iva.update
    !iva.field
  }

  def "generic field is recognized"() {
    when:
    def pa = getPropertyAdapter GenericStringBean, "value"

    then:

    pa.castRequired
    pa.type == String
    pa.declaringClass == GenericBean
  }
  
  interface GetterInterface {
    int getValue();
  }
        
  interface SetterGetterInterface extends GetterInterface {
    void setValue(int value);
  }
  
  interface SetterInterface {
    void setValue(int value);
  }
          
  interface GetterSetterInterface extends SetterInterface {
    int getValue();
  }
  
  final class GetterSetterClass implements GetterSetterInterface {
    public void setValue(int value) {}
    public int getValue() {}
  }
    
  // TAP5-1885
  def "split properties (getter in one supertype, setter in another)"() {
        
    when:
    def pa1 = getPropertyAdapter SetterGetterInterface, "value";
    def pa2 = getPropertyAdapter GetterSetterInterface, "value";
    def pa3 = getPropertyAdapter GetterSetterClass, "value";
      
    then:
    pa1.isRead();
    pa1.isUpdate();
    pa2.isRead();
    pa2.isUpdate();
    pa3.isRead();
    pa3.isUpdate();
  }
  
  public interface Baz { String getBar(); }
 
  public class AbstractFoo implements Baz {
    private String bar;
    public String getBar() { return bar; }
    public void setBar(String bar){ this.bar =bar; }
  }
  
  public class Foo extends AbstractFoo {}
  
  // TAP5-1548
  def "property expressions fails when using a supertype that implements an interface with a matching method"() {
        
    when:
    def pa = getPropertyAdapter AbstractFoo, "bar";
      
    then:
    pa.isRead();
    pa.isUpdate();
  }
  
  public static interface Entity<T extends Serializable>
  { 
    T getId(); 
  }
  
  public static interface NamedEntity extends Entity<Long> { 
    String getName(); 
  }

  // TAP5-1480
  def "exception when creating property conduits for generic interfaces"() {
    when:
    def paId = getPropertyAdapter Entity, "id";
    def paName = getPropertyAdapter NamedEntity, "name";
    
    then:
    paId != null
    paName != null
  }
  
  def getPropertyAdapter(clazz, name) {
    access.getAdapter(clazz).getPropertyAdapter(name)
  }

  private Method findMethod(Class beanClass, String methodName) {
    return beanClass.methods.find { it.name == methodName }
  }
  
 
  public static class TestData implements TestInterface {
  }
  
  // TAP5-2449
  def "default method is recognized"(){
    when:
    def pa = getPropertyAdapter(TestData, 'testString')
    then:
    pa != null
    
  }
}
