package com.github.davidmoten.rx.operators;

import static org.junit.Assert.assertEquals;
import static rx.Observable.from;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Test;

import rx.Observable;
import rx.functions.Func2;

import com.github.davidmoten.rx.Transformers;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

public class OperatorOrderedMergeTest {

    private static final Func2<Integer, Integer, Integer> comparator = new Func2<Integer, Integer, Integer>() {
        @Override
        public Integer call(Integer a, Integer b) {
            return a.compareTo(b);
        }
    };

    @Test
    public void testMerge() {
        // hang on to one stand-alone test like this so we can customize for
        // failure cases arriving out of testWithAllCombinationsFromPowerSet
        Observable<Integer> o1 = Observable.just(1, 2, 4, 10);
        Observable<Integer> o2 = Observable.just(3, 5, 11);
        check(o1, o2, 1, 2, 3, 4, 5, 10, 11);
    }

    @Test
    public void testWithAllCombinationsFromPowerSet() {
        // this test covers everything!
        for (int n = 0; n <= 10; n++) {
            Set<Integer> numbers = Sets.newTreeSet();
            for (int i = 1; i <= n; i++) {
                numbers.add(i);
            }
            for (Set<Integer> a : Sets.powerSet(numbers)) {
                TreeSet<Integer> x = Sets.newTreeSet(a);
                TreeSet<Integer> y = Sets.newTreeSet(Sets.difference(numbers, x));
                Observable<Integer> o1 = from(x);
                Observable<Integer> o2 = from(y);
                List<Integer> list = o1.compose(Transformers.orderedMergeWith(o2, comparator))
                        .toList().toBlocking().single();
                // System.out.println(x + "   " + y);
                assertEquals(Lists.newArrayList(numbers), list);
            }
        }
    }

    private static void check(Observable<Integer> o1, Observable<Integer> o2, Integer... values) {
        List<Integer> list = o1.compose(Transformers.orderedMergeWith(o2, comparator)).toList()
                .toBlocking().single();
        assertEquals(Arrays.asList(values), list);
    }
}

@@ -213,16 +213,54 @@
 TreeSet;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0Aimport
@@ -299,16 +299,37 @@
 rvable;%0A
+import rx.Scheduler;%0A
 import r
@@ -346,16 +346,49 @@
 s.Func2;
+%0Aimport rx.schedulers.Schedulers;
 %0A%0Aimport
@@ -1215,24 +1215,456 @@
 owerSet() %7B%0A
+        checkAllCombinationsFromPowerSet(Schedulers.immediate());%0A    %7D%0A%0A    @Test%0A    public void testWithAllCombinationsFromPowerSetAsync() %7B%0A        long t = System.currentTimeMillis();%0A        while (System.currentTimeMillis() - t %3C= TimeUnit.SECONDS.toMillis(5)) %7B%0A            checkAllCombinationsFromPowerSet(Schedulers.computation());%0A        %7D%0A    %7D%0A%0A    private void checkAllCombinationsFromPowerSet(Scheduler scheduler) %7B%0A
         // t
@@ -2122,16 +2122,39 @@
  from(x)
+.subscribeOn(scheduler)
 ;%0A      
@@ -2195,16 +2195,39 @@
  from(y)
+.subscribeOn(scheduler)
 ;%0A      

add async test for ordered merge