package kembe.sim;

import fj.Equal;
import fj.F;
import fj.P;
import fj.P2;
import fj.data.List;
import kembe.EventStreamHandler;
import kembe.EventStreamSubscriber;
import kembe.Time;
import kembe.sim.rand.RandomGen;
import kembe.scheduler.Clock;
import org.joda.time.Instant;
import org.joda.time.Seconds;
import org.junit.Test;

import java.util.Random;

import static fj.P.p;
import static fj.data.List.list;

public class RealtimeSimulatorTest {
    private RandomGen<Boolean> oneOfTen =
            RandomGen.randomInt( 0, 9 ).map( new F<Integer, Boolean>() {
                @Override public Boolean f(Integer integer) {
                    return (integer == 0);
                }
            } );

    private SignalHandler testDriver =
            new RandomSignalHandlerAdapter<Boolean>( oneOfTen ) {
                @Override protected P2<SignalHandler, List<Signal>> signalRandom(Signal signal, Boolean randomValue) {
                    if (signal.msg.startsWith( "OK" ))
                        return p( self(), List.<Signal>nil() );
                    else if (randomValue)
                        return p( self(), list( signal.follow( ResourceId.fromString( "testHandler" ), Time.quantumIncrement( signal.at ), "GET to the chopper" ) ) );
                    else
                        return p( self(), List.<Signal>nil() );
                }
            };

    private SignalHandler testHandler =
            new NonrandomSignalHandler() {
                @Override protected P2<SignalHandler, List<Signal>> signal(Signal signal, SignalHandlerContext context) {

                    final SignalHandler self = this;

                    if (signal.msg.startsWith( "GET" ))
                        return P.p( new NonrandomSignalHandler() {

                            @Override protected P2<SignalHandler, List<Signal>> signal(Signal signal, SignalHandlerContext context) {
                                if (Equal.stringEqual.eq( signal.msg, "self" ))
                                    return P.p( self, list( signal.followImmediately( ResourceId.fromString( "testDriver" ), "OK" ) ) );
                                else
                                    return P.p( self(), List.<Signal>nil() );
                            }
                        }.self(), list( signal.follow( ResourceId.fromString( "testHandler" ), signal.at.plus( Seconds.ONE.toStandardDuration() ), "self" ) ) );

                    return P.p( self(), List.<Signal>nil() );
                }
            };

    @Test
    public void simple() throws InterruptedException {


        Random r = new Random( 2 );
        Instant start = Time.now();
        SimulationBuilder.build()
                .addDriver( new Agent( ResourceId.fromString( "testDriver" ), start, testDriver ) )
                .addHandler( new Agent( ResourceId.fromString( "testHandler" ), start, testHandler ) )
                .realtime( Clock.seconds(), r )
                .open( EventStreamSubscriber.create( new EventStreamHandler<Signal>() {
                    @Override public void next(Signal signal) {
                        System.out.println( signal.at + ": " + Signal.chainShow.showS( signal ) + " ( " + Time.now().toString() + " )" );
                    }

                    @Override public void error(Exception e) {

                    }

                    @Override public void done() {

                    }
                } ) );

        Thread.sleep( 60000 );

    }


}

@@ -197,55 +197,55 @@
 be.s
-im.rand.RandomGen;%0Aimport kembe.scheduler.Clock
+cheduler.Clock;%0Aimport kembe.sim.rand.RandomGen
 ;%0Aim
@@ -305,31 +305,8 @@
 nds;
-%0Aimport org.junit.Test;
 %0A%0Aim
@@ -2495,16 +2495,18 @@
 %7D;%0A%0A    
+//
 @Test%0A  
@@ -2906,14 +2906,16 @@
 ock.
-second
+tenMilli
 s(),
@@ -3443,10 +3443,9 @@
 ep( 
-60
+1
 000 

Upgrade to java 7