package com.stolets.rxdiffutil.diffrequest;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.util.DiffUtil;

import com.stolets.rxdiffutil.internal.Constants;

import java.lang.ref.WeakReference;

import static com.stolets.rxdiffutil.internal.Preconditions.checkArgument;
import static com.stolets.rxdiffutil.internal.Preconditions.checkNotNull;

/**
 * The builder used to supply the required input to start difference calculation.
 */
public final class DiffRequestBuilder {
    @NonNull
    private final WeakReference<Activity> mActivityWeakRef;
    @NonNull
    private DiffUtil.Callback mDiffCallback;
    @NonNull
    private String mTag = Constants.DIFF_REQUEST_DEFAULT_TAG;
    private boolean mDetectMoves;

    /**
     * Constructs a new {@link DiffRequestBuilder} instance.
     *
     * @param activity The {@link Activity} that determines the lifecycle of the async calculations.
     *                 When the activity is destroyed and finished (isFinishing = true) all current calculations are stopped automatically.
     */
    public DiffRequestBuilder(@NonNull final Activity activity, @NonNull final DiffUtil.Callback diffCallback) {
        checkNotNull(activity, "activity must not be null!");
        checkNotNull(diffCallback, "diffCallback must not be null!");

        // Required fields
        this.mActivityWeakRef = new WeakReference<>(activity);
        this.mDiffCallback = diffCallback;
    }

    /**
     * @param detectMoves Determines whether the moves are detected during difference calculation.
     *                    Default is false.
     * @return {@link DiffRequestBuilder}.
     */
    @NonNull
    @SuppressWarnings("WeakerAccess")
    public DiffRequestBuilder detectMoves(final boolean detectMoves) {
        mDetectMoves = detectMoves;
        return this;
    }

    /**
     * @param tag A {@link String} that represents a unique identifier of the request.
     *            When you are making a new request the previous request with the same tag will be cancelled (if it is still in progress).
     *            You can skip it if your {@link Activity} manages just one {@link android.support.v7.widget.RecyclerView}.
     * @return {@link DiffRequestBuilder}.
     */
    @NonNull
    @SuppressWarnings("WeakerAccess")
    public DiffRequestBuilder tag(@NonNull final String tag) {
        checkNotNull(tag, "tag must not be null!");
        checkArgument(!tag.isEmpty(), "tag string must not be empty!");
        mTag = tag;
        return this;
    }

    /**
     * Builds the {@link DiffRequest} and returns {@link DiffRequestManagerWrapper} with the same tag and attached {@link DiffRequestManager}.
     *
     * @return {@link DiffRequestManagerWrapper} or null if the given activity has been destroyed.
     */
    @Nullable
    @SuppressWarnings("WeakerAccess")
    public DiffRequestManagerWrapper build() {
        final Activity activity = getActivity();
        DiffRequestManagerWrapper diffRequestManagerWrapper = null;

        if (activity != null) {
            final DiffRequestManager diffRequestManager = DiffRequestManagerRetriever.retrieve(activity);
            final DiffRequest diffRequest = new DiffRequest(this.mDetectMoves, this.mTag, this.mDiffCallback);

            diffRequestManager.addPendingRequest(diffRequest);
            diffRequestManagerWrapper = new DiffRequestManagerWrapper(diffRequestManager, this.mTag);
        }

        return diffRequestManagerWrapper;
    }

    /**
     * @return An {@link Activity} or null if it has been destroyed.
     */
    @Nullable
    @SuppressWarnings("WeakerAccess")
    public Activity getActivity() {
        return mActivityWeakRef.get();
    }

    /**
     * @return A concrete implementation of {@link DiffUtil.Callback}.
     */
    @NonNull
    @SuppressWarnings("WeakerAccess")
    public DiffUtil.Callback getDiffCallback() {
        return mDiffCallback;
    }

    /**
     * @return A tag string.
     */
    @NonNull
    @SuppressWarnings("WeakerAccess")
    public String getTag() {
        return mTag;
    }

    /**
     * @return DetectMoves boolean flag.
     */
    @SuppressWarnings("WeakerAccess")
    public boolean isDetectingMoves() {
        return mDetectMoves;
    }
}

@@ -114,52 +114,8 @@
 ll;%0A
-import android.support.annotation.Nullable;%0A
 impo
@@ -207,45 +207,8 @@
 s;%0A%0A
-import java.lang.ref.WeakReference;%0A%0A
 impo
@@ -518,75 +518,8 @@
 nal 
-WeakReference%3CActivity%3E mActivityWeakRef;%0A    @NonNull%0A    private 
 Diff
@@ -751,219 +751,234 @@
 ram 
-activity The %7B@link Activity%7D that determines the lifecycle of the async calculations.%0A     *                 When the activity is destroyed and finished (isFinishing = true) all current calculations are stopped
+diffCallback The concrete implementation of %7B@link DiffUtil.Callback%7D.%0A     *                     You can pass %7B@link com.stolets.rxdiffutil.DefaultDiffCallback%7D to update %7B@link android.support.v7.widget.RecyclerView.Adapter%7D
  aut
@@ -1046,42 +1046,8 @@
 nal 
-Activity activity, @NonNull final 
 Diff
@@ -1101,209 +1101,57 @@
 ull(
-activity, %22activity must not be null!%22);%0A        checkNotNull(diffCallback, %22diffCallback must not be null!%22);%0A%0A        // Required fields%0A        this.mActivityWeakRef = new WeakReference%3C%3E(activity);
+diffCallback, %22diffCallback must not be null!%22);%0A
 %0A   
@@ -2300,18 +2300,29 @@
  * B
-uil
+in
 ds the 
+constructed 
 %7B@li
@@ -2341,119 +2341,289 @@
 st%7D 
-and returns %7B@link DiffRequestManagerWrapper%7D with the same tag and attached %7B@link DiffRequestManager%7D.%0A     *
+to the activity lifecycle.%0A     *%0A     * @param activity The %7B@link Activity%7D that determines the lifecycle of the background calculations.%0A     *                 When the activity is destroyed and finished (isFinishing = true) all current calculations are cancelled automatically.
 %0A   
@@ -2672,56 +2672,55 @@
 er%7D 
-or null if the given activity has been destroyed
+you can use to start the difference calculation
 .%0A  
@@ -2723,39 +2723,38 @@
 .%0A     */%0A    @N
+onN
 ull
-able
 %0A    @SuppressWa
@@ -2818,24 +2818,22 @@
 er b
-uild() %7B%0A       
+indTo(@NonNull
  fin
@@ -2856,131 +2856,75 @@
 vity
- = getActivity();%0A        DiffRequestManagerWrapper diffRequestManagerWrapper = null;%0A%0A        if (activity != null) %7B%0A    
+) %7B%0A        checkNotNull(activity, %22activity must not be null!%22);%0A%0A
     
@@ -3021,20 +3021,16 @@
 ivity);%0A
-    
         
@@ -3129,36 +3129,32 @@
 back);%0A%0A        
-    
 diffRequestManag
@@ -3188,28 +3188,25 @@
 quest);%0A
-    
+%0A
         
 diffRequ
@@ -3201,35 +3201,14 @@
     
-diffRequestManagerWrapper =
+return
  new
@@ -3270,280 +3270,8 @@
 g);%0A
-        %7D%0A%0A        return diffRequestManagerWrapper;%0A    %7D%0A%0A    /**%0A     * @return An %7B@link Activity%7D or null if it has been destroyed.%0A     */%0A    @Nullable%0A    @SuppressWarnings(%22WeakerAccess%22)%0A    public Activity getActivity() %7B%0A        return mActivityWeakRef.get();%0A
     

Implement bindTo method instead of holding an activity instance