package com.alorma.github.ui.actions;
import android.content.Context;
import android.support.annotation.NonNull;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.Theme;
import com.alorma.github.R;
import com.alorma.github.injector.component.ApiComponent;
import com.alorma.github.sdk.bean.dto.request.EditIssueAssigneesRequestDTO;
import com.alorma.github.sdk.bean.dto.response.Issue;
import com.alorma.github.sdk.bean.info.IssueInfo;
import com.alorma.github.ui.utils.DialogUtils;
import com.alorma.gitskarios.core.client.TokenProvider;
import core.ApiClient;
import core.User;
import core.datasource.CloudDataSource;
import core.datasource.RestWrapper;
import core.datasource.RetrofitWrapper;
import core.datasource.SdkItem;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class AssigneeAction extends Action<Boolean> {
private Context context;
private ApiComponent apiComponent;
private IssueInfo issueInfo;
private List<User> users;
private List<User> removedUsers;
private MaterialDialog dialog;
@Inject ApiClient apiClient;
public AssigneeAction(Context context, ApiComponent apiComponent, IssueInfo issueInfo, List<User> users, List<User> removedUsers) {
this.context = context;
this.apiComponent = apiComponent;
this.issueInfo = issueInfo;
this.users = users;
this.removedUsers = removedUsers;
inject();
}
private void inject() {
apiComponent.inject(this);
}
@Override
public Action<Boolean> execute() {
dialog = new DialogUtils().builder(context).content(R.string.changing_assignee).progress(true, 0).theme(Theme.DARK).show();
create(users, removedUsers).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::returnResult, Throwable::printStackTrace);
return this;
}
public Observable<Boolean> create(List<User> addUsers, List<User> removedUsers) {
RetrofitWrapper wrapper = new RetrofitWrapper(apiClient, TokenProvider.getInstance().getToken()) {
@Override
protected AssigneesService get(Retrofit retrofit) {
return retrofit.create(AssigneesService.class);
}
};
return new CloudDataSource<Void, Boolean>(wrapper) {
@Override
protected Observable<SdkItem<Boolean>> execute(SdkItem<Void> request, RestWrapper service) {
EditIssueAssigneesRequestDTO dtoAdd = createDto(addUsers);
Observable<Issue> addAssignees = addAssignees(dtoAdd, service.get());
EditIssueAssigneesRequestDTO dtoRemove = createDto(removedUsers);
Observable<Issue> removeAssignees = removeAssignees(dtoRemove, service.get());
return Observable.merge(addAssignees, removeAssignees).all(issue -> true).all(Boolean::booleanValue).map(SdkItem::new);
}
}.execute(null, wrapper).map(SdkItem::getK);
}
@NonNull
private EditIssueAssigneesRequestDTO createDto(List<User> users) {
EditIssueAssigneesRequestDTO dto = new EditIssueAssigneesRequestDTO();
dto.assignees = new ArrayList<>();
for (User us : users) {
dto.assignees.add(us.getLogin());
}
return dto;
}
public Observable<Issue> addAssignees(EditIssueAssigneesRequestDTO dto, AssigneesService service) {
return Observable.defer(() -> {
Call<Issue> call = service.changeAssignees(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, dto);
return executeCall(call);
});
}
public Observable<Issue> removeAssignees(EditIssueAssigneesRequestDTO dto, AssigneesService service) {
return Observable.defer(() -> {
Call<Issue> call = service.removeAssignees(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, dto);
return executeCall(call);
});
}
private Observable<Issue> executeCall(Call<Issue> call) {
try {
Response<Issue> response = call.execute();
if (response.isSuccessful()) {
return Observable.just(response.body());
} else {
return Observable.error(new Exception(response.errorBody().string()));
}
} catch (Exception e) {
return Observable.error(e);
}
}
private void returnResult(boolean t) {
if (dialog != null) {
dialog.dismiss();
}
if (getCallback() != null) {
getCallback().onResult(t);
}
}
@Override
public void onNext(Boolean aBoolean) {
}
}