package ioc.specs

import org.apache.tapestry5.internal.plastic.PlasticClassLoader
import org.apache.tapestry5.internal.plastic.PlasticInternalUtils
import org.apache.tapestry5.internal.plastic.asm.ClassWriter
import org.apache.tapestry5.ioc.def.ServiceDef3
import org.apache.tapestry5.ioc.internal.services.PlasticProxyFactoryImpl
import org.apache.tapestry5.ioc.services.PlasticProxyFactory
import org.slf4j.Logger
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
import org.apache.tapestry5.ioc.*
import org.apache.tapestry5.ioc.internal.*

import static org.apache.tapestry5.internal.plastic.asm.Opcodes.*

class DefaultModuleDefImplSpec extends Specification {

  @Shared
  PlasticProxyFactory proxyFactory = new PlasticProxyFactoryImpl(Thread.currentThread().contextClassLoader, null)

  @Shared
  OperationTracker tracker = new QuietOperationTracker()

  Logger logger = Mock()

  def "toString() of module lists services in the module"() {
    when:

    def md = module SimpleModule

    then:

    md.toString() == "ModuleDef[$SimpleModule.name Barney, Fred, Wilma]"
  }

  def "serviceIds contains all service ids"() {
    def md = module SimpleModule

    expect:

    md.serviceIds == ["Fred", "Barney", "Wilma"] as Set
  }

  def "ServiceDef obtainable by service id"() {
    def md = module SimpleModule

    when:

    def sd = md.getServiceDef "fred"

    then:

    sd.serviceId == "Fred"
    sd.serviceInterface == FieService
    sd.toString().contains "${SimpleModule.name}.buildFred()"
    sd.serviceScope == ScopeConstants.DEFAULT
    !sd.eagerLoad
    sd.markers.empty

    when:

    sd = md.getServiceDef("Wilma")

    then:

    sd.eagerLoad
  }

  def "ModuleDef exposes decorator methods as DecoratorDefs"() {
    def md = module SimpleModule

    when:

    def decos = md.decoratorDefs

    then:

    decos.size() == 1

    def deco = decos.find()

    deco.decoratorId == "Logging"
    deco.toString().contains "${SimpleModule.name}.decorateLogging(Class, Object)"
  }

  def "@ServiceId annotation on service builder method overrides naming convention"() {
    when:

    def md = module ServiceIdViaAnnotationModule

    then:

    md.getServiceDef("FooService") != null
  }

  def "@ServiceId on implementation class overrides default id from ServiceBinder.bind() default"() {
    when:

    def md = module ServiceIdViaAnnotationModule

    then:

    md.getServiceDef("BarneyService") != null
  }

  def "@Named annotation on service builder method overrides naming convention"() {
    when:

    def md = module NamedServiceModule

    then:

    md.getServiceDef("BazService") != null
  }

  def "@Named annotation on service implementation class overrides ServiceBinder.bind() default"() {
    when:

    def md = module NamedServiceModule

    then:

    md.getServiceDef("QuuxService") != null
  }

  def "naming convention for a service builder method named build() is derived from the return type"() {
    when:

    def md = module DefaultServiceIdModule

    then:

    md.getServiceDef("FieService") != null
  }

  def "conflicting service ids result in an exception"() {
    when:

    module ServiceIdConflictMethodModule

    then:

    RuntimeException ex = thrown()

    ex.message.contains "Service Fred (defined by ${ServiceIdConflictMethodModule.name}.buildFred()"
    ex.message.contains "conflicts with previously defined service defined by ${ServiceIdConflictMethodModule.name}.buildFred(Object)"
  }

  def "a service builder method may not return void"() {
    when:

    module VoidBuilderMethodModule

    then:

    RuntimeException ex = thrown()

    ex.message.contains "${VoidBuilderMethodModule.name}.buildNull()"
    ex.message.contains "but the return type (void) is not acceptable"
  }

  def "a service builder method may not return an array"() {
    when:

    module BuilderMethodModule

    then:

    RuntimeException ex = thrown()

    ex.message.contains "${BuilderMethodModule.name}.buildStringArray()"
    ex.message.contains "but the return type (java.lang.String[])"
  }

  @Unroll
  def "A decorator method #desc"() {
    when:

    module moduleClass

    then:

    RuntimeException e = thrown()

    e.message.contains expectedText

    where:

    moduleClass                    | expectedText        | desc
    PrimitiveDecoratorMethodModule | "decoratePrimitive" | "may not return a primitive type"
    ArrayDecoratorMethodModule     | "decorateArray"     | "may not return an array"
  }

  @Unroll
  def "#desc"() {
    when:

    def md = module moduleClass

    then:

    def defs = md.contributionDefs

    defs.size() == 1

    def cd = defs.find()

    cd.serviceId == serviceId

    cd.toString().contains "${moduleClass.name}.$methodSignature"

    where:

    moduleClass                | serviceId | methodSignature                           | desc
    SimpleModule               | "Barney"  | "contributeBarney(Configuration)"         | "contribution without annotation to configuration"
    OrderedConfigurationModule | "Ordered" | "contributeOrdered(OrderedConfiguration)" | "contribution to ordered configuration"
    MappedConfigurationModule  | "Mapped"  | "contributeMapped(MappedConfiguration)"   | "contribution to mapped configuration"
  }

  @Unroll
  def "service contribution method that #desc throws an exception"() {

    when:

    module moduleClass

    then:

    RuntimeException e = thrown()

    e.message.contains message

    where:

    moduleClass                         | message                                                                                                | desc

    NoUsableContributionParameterModule | "does not contain a parameter of type Configuration, OrderedConfiguration or MappedConfiguration"      | "does not include configuration parameter"
    TooManyContributionParametersModule | "contains more than one parameter of type Configuration, OrderedConfiguration, or MappedConfiguration" | "includes more than one configuration parameter"
  }

  def "using defaults for ServiceBinder.bind()"() {

    when:

    def md = module AutobuildModule
    ServiceDef3 sd = md.getServiceDef "stringholder"

    then:

    sd.serviceInterface == StringHolder
    sd.serviceId == "StringHolder"
    sd.serviceScope == ScopeConstants.DEFAULT
    !sd.isEagerLoad()
    sd.markers.empty
    !sd.preventDecoration
  }

  def "overriding defaults for ServiceBinder.bind()"() {

    when:

    def md = module ComplexAutobuildModule
    ServiceDef3 sd = md.getServiceDef "sh"

    then:

    sd.serviceInterface == StringHolder
    sd.serviceId == "SH"
    sd.serviceScope == "magic"
    sd.eagerLoad
    sd.preventDecoration
  }

  def "implementation class for ServiceBinder.bind() must have a public constructor"() {
    when:

    module UninstantiableAutobuildServiceModule

    then:

    RuntimeException e = thrown()

    e.message.contains "Class org.apache.tapestry5.ioc.internal.RunnableServiceImpl (implementation of service 'Runnable') does not contain any public constructors."
  }

  def "the bind() method of a module class must be a static method"() {
    when:

    module NonStaticBindMethodModule

    then:

    RuntimeException e = thrown()

    e.message.contains "Method org.apache.tapestry5.ioc.internal.NonStaticBindMethodModule.bind(ServiceBinder)"
    e.message.contains "appears to be a service binder method, but is an instance method, not a static method"
  }

  def "when autobuilding a service implementation, the constructor with the most parameters is chosen"() {
    ServiceBuilderResources resources = Mock()

    when:

    def md = module MutlipleAutobuildServiceConstructorsModule

    def sd = md.getServiceDef "stringholder"

    then:

    sd != null

    0 * _

    when:

    def oc = sd.createServiceCreator(resources)
    def holder = oc.createObject()

    holder.value = "foo"

    then:

    holder instanceof StringHolder
    holder.value == "FOO"

    _ * resources.serviceId >> "StringHolder"
    _ * resources.logger >> logger
    _ * resources.serviceInterface >> StringHolder
    1 * resources.getService("ToUpperCaseStringHolder", StringHolder) >> new ToUpperCaseStringHolder()
    _ * resources.tracker >> tracker

    1 * logger.debug(_) >> { args ->
      assert args[0].contains(
          "Invoking constructor org.apache.tapestry5.ioc.internal.MultipleConstructorsAutobuildService(StringHolder)")
    }

    0 * _
  }

  def "an exception inside a bind() method bubbles up"() {
    when:

    module ExceptionInBindMethod

    then:

    RuntimeException e = thrown()

    e.message.contains "Error invoking service binder method org.apache.tapestry5.ioc.internal.ExceptionInBindMethod.bind(ServiceBinder)"
    e.message.contains "at ExceptionInBindMethod.java"
    e.message.contains "Really, how often is this going to happen?"
  }

  def "@EagerLoad annotation on service implementation class is reflected in the ServiceDef"() {
    when:

    def md = module EagerLoadViaAnnotationModule
    def sd = md.getServiceDef "runnable"

    then:

    sd.eagerLoad
  }

  private DefaultModuleDefImpl module(moduleClass) {
    new DefaultModuleDefImpl(moduleClass, logger, proxyFactory)
  }

  def "marker annotations on the service builder method are available in the ServiceDef"() {

    when:

    def md = module MarkerModule
    def sd = md.getServiceDef "greeter"

    then:

    sd.markers == [BlueMarker] as Set
  }

  def "marker annotations specified via ServiceBinder is available in the ServiceDef"() {
    when:

    def md = module MarkerModule
    def sd = md.getServiceDef "redgreeter"

    then:

    sd.markers == [RedMarker] as Set
  }

  def "marker annotation on the implementation class is available in the ServiceDef"() {
    when:

    def md = module MarkerModule
    def sd = md.getServiceDef "SecondRedGreeter"

    then:

    sd.markers == [RedMarker] as Set
  }

  def "marker annotation from ServiceBinder and implementation class are merged"() {
    when:

    def md = module MarkerModule
    def sd = md.getServiceDef "SurprisinglyBlueGreeter"

    then:

    sd.markers == [RedMarker, BlueMarker] as Set
  }

  def "Multiple marker annotations can be added to service via ServiceBindingOptions"() {
	  when:
  
	  def md = module MarkerModule
	  def sd = md.getServiceDef "ColorfulGreeter"
  
	  then:
  
	  sd.markers == [RedMarker, BlueMarker] as Set
	}
  
  def "public synthetic methods on module class are ignored"() {
    def moduleClass = createSyntheticModuleClass()

    when:

    def md = module moduleClass

    then:

    md.serviceIds.size() == 1
  }
  
  def "Methods overridden from Object are ignored"() {

    when:

    def md = module ModuleWithOverriddenObjectMethods

    then:

    md.serviceIds.size() == 1
  }


  private createSyntheticModuleClass() {

    def cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES)

    cw.visit(V1_5, ACC_PUBLIC, "EnhancedSyntheticMethodModule", null,
        PlasticInternalUtils.toInternalName(SyntheticMethodModule.name), null);

    def mv = cw.visitMethod ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "synth", "()V", null, null
    mv.visitCode()
    mv.visitInsn RETURN
    mv.visitEnd()

    cw.visitEnd()

    def bytecode = cw.toByteArray()

    ClassLoader loader = Thread.currentThread().contextClassLoader

    PlasticClassLoader plasticLoader = new PlasticClassLoader(loader, new NoopClassLoaderDelegate())

    return plasticLoader.defineClassWithBytecode("EnhancedSyntheticMethodModule", bytecode)
  }
}
