package com.veyndan.paper.reddit.post.media.mutator;

import com.google.common.collect.ImmutableList;
import com.veyndan.paper.reddit.post.model.Post;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.functions.Function;

public final class Mutators {

    private Mutators() {
        throw new AssertionError("No instances.");
    }

    /**
     * All available mutator factories.
     * <p>
     * Note that the order of the mutator factories is the order in which the post will be
     * checked for applicability of mutation.
     * <p>
     * Example if the {@link TwitterMutatorFactory} was set
     * after {@link LinkMutatorFactory} then the post would see if the {@link LinkMutatorFactory} is
     * applicable to mutate the post first, and if {@code false}, then {@link TwitterMutatorFactory}
     * would check if it is applicable. In this case the {@link TwitterMutatorFactory} would never
     * be checked for applicability or be applicable, as if the post contains a link, then
     * {@link LinkMutatorFactory} would be applicable, then mutation would stop. If
     * {@link LinkMutatorFactory} isn't applicable, then the post doesn't have a link, so
     * {@link TwitterMutatorFactory} would never be applicable. Obviously this means that
     * {@link LinkMutatorFactory} should occur <b><em>after</em></b> {@link TwitterMutatorFactory}.
     */
    private static final List<MutatorFactory> MUTATOR_FACTORIES = ImmutableList.of(
            TwitterMutatorFactory.create(),
            XkcdMutatorFactory.create(),
            ImgurMutatorFactory.create(),
            ImgflipMutatorFactory.create(),
            ImageMutatorFactory.create(),
            TextMutatorFactory.create(),
            LinkImageMutatorFactory.create(),
            LinkMutatorFactory.create()
    );

    /**
     * Mutate a list of posts by the first mutator which is applicable to mutate the post.
     */
    public static Function<Post, Single<Post>> mutate() {
        return post -> Observable.fromIterable(MUTATOR_FACTORIES)
                .flatMapMaybe(mutatorFactory -> mutatorFactory.mutate(post))
                .first(post);
    }
}

@@ -51,56 +51,8 @@
 r;%0A%0A
-import com.google.common.collect.ImmutableList;%0A
 impo
@@ -101,32 +101,8 @@
 t;%0A%0A
-import java.util.List;%0A%0A
 impo
@@ -1368,20 +1368,26 @@
 c final 
-List
+Observable
 %3CMutator
@@ -1419,24 +1419,28 @@
 S = 
-ImmutableList.of
+Observable.fromArray
 (%0A  
@@ -1977,32 +1977,8 @@
  -%3E 
-Observable.fromIterable(
 MUTA
@@ -1990,17 +1990,16 @@
 ACTORIES
-)
 %0A       

Store Mutator Factories in Observable so no need for ImmutableList as Observables are immutable