package au.gov.amsa.risky.format;

import static com.google.common.base.Optional.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.Ignore;
import org.junit.Test;

import rx.Observable;
import au.gov.amsa.risky.format.OperatorMinEffectiveSpeedThreshold.FixWithPreAndPostEffectiveSpeed;

public class OperatorMinEffectiveSpeedThresholdTest {

    @Test
    public void test() {
        long t = 1000;
        long diff = TimeUnit.MINUTES.toMillis(20);
        Fix a = createFix(t, 135f);
        t += diff;
        Fix b = createFix(t, 135.01f);
        t += diff;
        Fix c = createFix(t, 135.02f);
        t += diff;
        Fix d = createFix(t, 135.03f);
        t += diff;
        Fix e = createFix(t, 135.04f);
        t += TimeUnit.MINUTES.toMillis(15);
        Fix f = createFix(t, 135.05f);

        List<FixWithPreAndPostEffectiveSpeed> list =
        // fixes
        Observable.from(Arrays.asList(a, b, c, d, e, f))
        // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                // block and get as a list
                .toList().toBlocking().single();
        for (Object o : list)
            System.out.println(o);
        assertEquals(135.02, list.get(0).fix().lon(), 0.0001);
        assertEquals(1.77, list.get(0).preEffectiveSpeedKnots(), 0.01);
    }

    private Fix createFix(long t, float lon) {
        return new Fix(213456789, -10f, lon, t, of(12), of((short) 1),
                of(NavigationalStatus.ENGAGED_IN_FISHING), of(7.5f), of(45f), of(46f), AisClass.B);
    }

    @Test
    public void testOnEmpty() {
        List<FixWithPreAndPostEffectiveSpeed> list = Observable.<HasFix> empty()
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertTrue(list.isEmpty());
    }

    @Test
    public void testSingle() {
        List<FixWithPreAndPostEffectiveSpeed> list = Observable.just(createFix(0, 135.0f))
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertTrue(list.isEmpty());
    }

    @Test
    public void testTwoSmallGapReturnsNothing() {
        List<FixWithPreAndPostEffectiveSpeed> list = Observable
                .just(createFix(0, 135.0f), createFix(100, 135.01f))
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertTrue(list.isEmpty());
    }

    @Test
    public void testTwoLargeGapReturnsNothing() {
        List<FixWithPreAndPostEffectiveSpeed> list = Observable
                .just(createFix(0, 135.0f), createFix(TimeUnit.HOURS.toMillis(1), 135.01f))
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertTrue(list.isEmpty());
    }

    @Test
    public void testThreeSmallGapThenLargeGapReturnsNothing() {
        List<FixWithPreAndPostEffectiveSpeed> list = Observable
                .just(createFix(0, 135.0f), createFix(100, 135.05f),
                        createFix(TimeUnit.MINUTES.toMillis(60), 135.01f))
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertTrue(list.isEmpty());
    }

    @Test
    @Ignore
    public void testThreeLargeGapThenLargeGapReturnsSecond() {
        Fix a = createFix(0, 135.0f);
        Fix b = createFix(TimeUnit.HOURS.toMillis(31), 135.05f);
        Fix c = createFix(TimeUnit.MINUTES.toMillis(62), 135.01f);
        List<FixWithPreAndPostEffectiveSpeed> list = Observable.just(a, b, c)
                // aggregate stats
                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))
                .toList().toBlocking().single();
        assertEquals(b.fix().lon(), list.get(0).fix().lon(), 0.0001);
    }
}

@@ -123,16 +123,60 @@
 Equals;%0A
+import static org.junit.Assert.assertFalse;%0A
 import s
@@ -302,33 +302,8 @@
 t;%0A%0A
-import org.junit.Ignore;%0A
 impo
@@ -3792,20 +3792,8 @@
 est%0A
-    @Ignore%0A
     
@@ -3916,36 +3916,38 @@
 ateFix(TimeUnit.
-HOUR
+MINUTE
 S.toMillis(31), 
@@ -3946,26 +3946,25 @@
 is(31), 135.
-05
+1
 f);%0A        
@@ -4012,26 +4012,25 @@
 is(62), 135.
-01
+2
 f);%0A        
@@ -4268,32 +4268,69 @@
 ing().single();%0A
+        assertFalse(list.isEmpty());%0A
         assertEq

fix unit test