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.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());
    }
}

@@ -250,24 +250,49 @@
 .TimeUnit;%0A%0A
+import org.junit.Ignore;%0A
 import org.j
@@ -3255,11 +3255,1100 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testThreeSmallGapThenLargeGapReturnsNothing() %7B%0A        List%3CFixWithPreAndPostEffectiveSpeed%3E list = Observable%0A                .just(createFix(0, 135.0f), createFix(100, 135.05f),%0A                        createFix(TimeUnit.MINUTES.toMillis(60), 135.01f))%0A                // aggregate stats%0A                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))%0A                .toList().toBlocking().single();%0A        assertTrue(list.isEmpty());%0A    %7D%0A%0A    @Test%0A    @Ignore%0A    public void testThreeLargeGapThenLargeGapReturnsSecond() %7B%0A        Fix a = createFix(0, 135.0f);%0A        Fix b = createFix(TimeUnit.HOURS.toMillis(31), 135.05f);%0A        Fix c = createFix(TimeUnit.MINUTES.toMillis(62), 135.01f);%0A        List%3CFixWithPreAndPostEffectiveSpeed%3E list = Observable.just(a, b, c)%0A                // aggregate stats%0A                .lift(new OperatorMinEffectiveSpeedThreshold(TimeUnit.MINUTES.toMillis(30)))%0A                .toList().toBlocking().single();%0A        assertEquals(b.fix().lon(), list.get(0).fix().lon(), 0.0001);%0A    %7D
 %0A%7D%0A

add unit tests