package ru.rulex.conclusion.dagger;

import javax.inject.Named;


import org.junit.Test;
import ru.rulex.conclusion.Model;
import ru.rulex.conclusion.PhraseBuildersFacade.DaggerEventPhrasesBuilder;
import ru.rulex.conclusion.PhraseBuildersFacade.DaggerMutableEventPhraseBuilder;

import static dagger.ObjectGraph.create;
import static junit.framework.Assert.fail;
import static junit.framework.TestCase.assertTrue;
import static org.fest.assertions.api.Assertions.assertThat;
import static ru.rulex.conclusion.PhraseBuildersFacade.environment;
import static ru.rulex.conclusion.PhraseBuildersFacade.var;
import static ru.rulex.conclusion.dagger.DaggerImmutableDependencyAnalyzerModule.*;
import static ru.rulex.conclusion.dagger.DaggerMutableDependencyAnalyzerModule.*;
import static ru.rulex.conclusion.delegate.ProxyUtils.callOn;

public class DaggerEventOrientedEngineTest
{
  @Test
  public void testSimpleDaggerBuilder()
  {
    final DaggerEventPhrasesBuilder builder = create(
      $expression(
        $less( 19, callOn( Model.class ).getInteger() ),
        $less( 19, callOn( Model.class ).getOtherInteger() ),
        $more( 56.78f, callOn( Model.class ).getFloat() ) ))
      .get( DaggerEventPhrasesBuilder.class );
    
    assertThat( builder.sync( Model.values( 20, 78 ) ) ).isTrue();
  }

  @Test
  public void testMutableDaggerBuilder()
  {
    final String val1 = "x1";
    final String val2 = "x2";

    final DaggerMutableEventPhraseBuilder mutableBuilder = create(
      $mutableExpression(
        $less0( 12, val1 ),
        $less0( 13, val2 )
      )
    ).get( DaggerMutableEventPhraseBuilder.class );

    final boolean result = mutableBuilder.populateFrom(
      environment(
        var( val1, callOn( Model.class ).getInteger() ),
        var( val2, callOn( Model.class ).getInteger() )
      )
    ).sync( Model.values( 20, 78 ) );

    assertTrue( result );
  }

  @Test(expected = IllegalStateException.class)
  public void testMutableDaggerBuilderWithMissedValue()
  {
    final DaggerMutableEventPhraseBuilder mutableBuilder = create(
      $mutableExpression(
        $less0( 64, "a" ),
        $less0( 678, "b" ),
        $less0( 6755656, "c" )
      )
    ).get( DaggerMutableEventPhraseBuilder.class );

    mutableBuilder.populateFrom(
      environment(
        var( "a", callOn( Model.class ).getInteger() )
      )
    ).sync( Model.values( 20, 78 ) );
    fail();
  }

  /*
  TODO: implement like this API , with AnnotationProcessor
  public void testAnnotationApi() {
    //@Module(addsTo = RootModule.class, injects = { C.class, D.class })
    @Expression( onClass = Model.class,
        conditions = { callOn( Model.class ).getFloat(), callOn( Model.class ).getFloat() } )

  }
  */

  interface Expression
  {
    @Less( "{value}" )
    void someValue1( @Named( "value" ) Integer value );

    @More( "{value}" )
    void someValue2( @Named( "value" ) Integer value0 );
  }
}

@@ -314,16 +314,67 @@
 create;%0A
+import static junit.framework.Assert.assertEquals;%0A
 import s
@@ -1951,49 +1951,9 @@
 Test
-(expected = IllegalStateException.class)
 %0A
+
   pu
@@ -2244,24 +2244,36 @@
 r.class );%0A%0A
+    try %7B%0A  
     mutableB
@@ -2291,32 +2291,34 @@
 lateFrom(%0A      
+  
 environment(%0A   
@@ -2306,32 +2306,34 @@
    environment(%0A
+  
         var( %22a%22
@@ -2369,34 +2369,38 @@
 teger() )%0A      
+ 
+ 
 )%0A
+  
     ).sync( Mode
@@ -2417,24 +2417,171 @@
 20, 78 ) );%0A
+    %7D catch (IllegalStateException ex) %7B%0A      assertEquals( ex.getMessage(), %22Undefined variables was found: b,c%22);%0A    %7D catch (Exception e) %7B%0A  
     fail();%0A
@@ -2576,24 +2576,30 @@
     fail();%0A
+    %7D%0A
   %7D%0A%0A  /*%0A  

fix test method testMutableDaggerBuilderWithMissedValue