/*
 * Copyright (c) 2015 PocketHub
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.pockethub.android.ui.issue;

import android.util.Log;

import com.github.pockethub.android.rx.RxProgress;
import com.meisolsson.githubsdk.core.ServiceGenerator;
import com.meisolsson.githubsdk.model.Page;
import com.meisolsson.githubsdk.model.Repository;
import com.meisolsson.githubsdk.model.User;
import com.github.pockethub.android.R;
import com.github.pockethub.android.ui.BaseProgressDialog;
import com.github.pockethub.android.ui.BaseActivity;
import com.github.pockethub.android.util.ToastUtils;
import com.meisolsson.githubsdk.service.issues.IssueAssigneeService;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

import static java.lang.String.CASE_INSENSITIVE_ORDER;

/**
 * Dialog helper to display a list of assignees to select one from
 */
public class AssigneeDialog extends BaseProgressDialog {

    private static final String TAG = "AssigneeDialog";

    private List<User> collaborators;

    private final int requestCode;

    private final BaseActivity activity;

    private final Repository repository;

    /**
     * Create dialog helper to display assignees
     *
     * @param activity
     * @param requestCode
     * @param repository
     */
    public AssigneeDialog(final BaseActivity activity,
            final int requestCode, final Repository repository) {
        super(activity);
        this.activity = activity;
        this.requestCode = requestCode;
        this.repository = repository;
    }

    private void load(final User selectedAssignee) {
        getPageAndNext(1)
                .flatMap(page -> Observable.fromIterable(page.items()))
                .toSortedList((o1, o2) -> CASE_INSENSITIVE_ORDER.compare(o1.login(), o2.login()))
                .compose(RxProgress.bindToLifecycle(activity, R.string.loading_collaborators))
                .subscribe(loadedCollaborators -> {
                    collaborators = loadedCollaborators;

                    show(selectedAssignee);
                }, error -> {
                    Log.d(TAG, "Exception loading collaborators", error);
                    ToastUtils.show(activity, error, R.string.error_collaborators_load);
                });
    }

    private Observable<Page<User>> getPageAndNext(int i) {
        return ServiceGenerator.createService(activity, IssueAssigneeService.class)
                .getAssignees(repository.owner().login(), repository.name(), i)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMapObservable(response -> {
                    Page<User> page = response.body();
                    if (page.next() == null) {
                        return Observable.just(page);
                    }

                    return Observable.just(page)
                            .concatWith(getPageAndNext(page.next()));
                });
    }


    /**
     * Show dialog with given assignee selected
     *
     * @param selectedAssignee
     */
    public void show(User selectedAssignee) {
        if (collaborators == null) {
            load(selectedAssignee);
            return;
        }

        int checked = -1;
        if (selectedAssignee != null) {
            for (int i = 0; i < collaborators.size(); i++) {
                if (selectedAssignee.login().equals(collaborators.get(i).login())) {
                    checked = i;
                }
            }
        }
        AssigneeDialogFragment.show(activity, requestCode,
                activity.getString(R.string.select_assignee), null, new ArrayList<>(collaborators),
                checked);
    }
}

@@ -1266,16 +1266,44 @@
 rvable;%0A
+import io.reactivex.Single;%0A
 import i
@@ -1646,47 +1646,8 @@
 %22;%0A%0A
-    private List%3CUser%3E collaborators;%0A%0A
     
@@ -1758,24 +1758,78 @@
 epository;%0A%0A
+    private final Single%3CList%3CUser%3E%3E assigneeSingle;%0A%0A
     /**%0A    
@@ -2224,75 +2224,33 @@
 ry;%0A
-    %7D%0A%0A    private void load(final User selectedAssignee) %7B%0A       
+%0A        assigneeSingle =
  get
@@ -2550,355 +2550,14 @@
    .
-subscribe(loadedCollaborators -%3E %7B%0A                    collaborators = loadedCollaborators;%0A%0A                    show(selectedAssignee);%0A                %7D, error -%3E %7B%0A                    Log.d(TAG, %22Exception loading collaborators%22, error);%0A                    ToastUtils.show(activity, error, R.string.error_collaborators_load);%0A                %7D
+cache(
 );%0A 
@@ -3421,19 +3421,40 @@
         
-if 
+assigneeSingle.subscribe
 (collabo
@@ -3464,86 +3464,17 @@
 ors 
-== null)
+-%3E
  %7B%0A    
-        load(selectedAssignee);%0A            return;%0A        %7D%0A%0A
     
@@ -3495,32 +3495,36 @@
 d = -1;%0A        
+  
+  
 if (selectedAssi
@@ -3531,32 +3531,36 @@
 gnee != null) %7B%0A
+    
             for 
@@ -3600,24 +3600,28 @@
 e(); i++) %7B%0A
+    
             
@@ -3709,24 +3709,28 @@
             
+    
 checked = i;
@@ -3738,34 +3738,40 @@
                 
-%7D%0A
+    %7D%0A  
             %7D%0A  
@@ -3766,26 +3766,31 @@
         
-%7D%0A
+  %7D%0A   
         
 %7D%0A      
@@ -3773,34 +3773,39 @@
    %7D%0A           
+ 
 %7D%0A
+    
         Assignee
@@ -3847,16 +3847,20 @@
 stCode,%0A
+    
         
@@ -3963,24 +3963,28 @@
             
+    
 checked);%0A  
@@ -3981,16 +3981,197 @@
 ecked);%0A
+        %7D, error -%3E %7B%0A            Log.d(TAG, %22Exception loading collaborators%22, error);%0A            ToastUtils.show(activity, error, R.string.error_collaborators_load);%0A        %7D);%0A
     %7D%0A%7D%0A

Improve logic flow of loading assignees