package com.fastaccess.ui.modules.repos.issues.issue.details;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.fastaccess.R;
import com.fastaccess.data.dao.AssigneesRequestModel;
import com.fastaccess.data.dao.IssueRequestModel;
import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UsersListModel;
import com.fastaccess.data.dao.model.AbstractRepo;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.data.service.IssueService;
import com.fastaccess.data.service.NotificationService;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.PrefGetter;
import com.fastaccess.helper.RxHelper;
import com.fastaccess.provider.rest.RestProvider;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import java.util.ArrayList;
import retrofit2.Response;
import rx.Observable;
/**
* Created by Kosh on 10 Dec 2016, 9:23 AM
*/
class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements IssuePagerMvp.Presenter {
private Issue issueModel;
private int issueNumber;
private String login;
private String repoId;
private boolean isCollaborator;
private boolean showToRepoBtn;
@Nullable @Override public Issue getIssue() {
return issueModel;
}
@Override public void onError(@NonNull Throwable throwable) {
if (RestProvider.getErrorCode(throwable) == 404) {
sendToView(IssuePagerMvp.View::onFinishActivity);
} else {
onWorkOffline(issueNumber, login, repoId);
}
super.onError(throwable);
}
@Override public void onActivityCreated(@Nullable Intent intent) {
if (intent != null && intent.getExtras() != null) {
issueModel = intent.getExtras().getParcelable(BundleConstant.ITEM);
issueNumber = intent.getExtras().getInt(BundleConstant.ID);
login = intent.getExtras().getString(BundleConstant.EXTRA);
repoId = intent.getExtras().getString(BundleConstant.EXTRA_TWO);
showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE);
if (issueModel != null) {
issueNumber = issueModel.getNumber();
sendToView(IssuePagerMvp.View::onSetupIssue);
return;
} else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
getIssueFromApi();
return;
}
}
sendToView(IssuePagerMvp.View::onSetupIssue);
}
private void getIssueFromApi() {
Observable<Issue> observable = RestProvider.getIssueService().getIssue(login, repoId, issueNumber)
.flatMap(issue -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
(issue, booleanResponse) -> {
isCollaborator = booleanResponse.code() == 204;
return issue;
});
makeRestCall(observable, this::setupIssue);
}
private void setupIssue(Issue issue) {
issueModel = issue;
issueModel.setRepoId(repoId);
issueModel.setLogin(login);
sendToView(IssuePagerMvp.View::onSetupIssue);
}
@Override public void onWorkOffline(long issueNumber, @NonNull String repoId, @NonNull String login) {
if (issueModel == null) {
manageSubscription(RxHelper.getObserver(Issue.getIssueByNumber((int) issueNumber, repoId, login))
.subscribe(issueModel1 -> {
if (issueModel1 != null) {
issueModel = issueModel1;
sendToView(IssuePagerMvp.View::onSetupIssue);
}
}));
} else {
sendToView(BaseMvp.FAView::hideProgress);
}
}
@Override public boolean isOwner() {
if (getIssue() == null) return false;
User userModel = getIssue() != null ? getIssue().getUser() : null;
Login me = Login.getUser();
PullsIssuesParser parser = PullsIssuesParser.getForIssue(getIssue().getHtmlUrl());
return (userModel != null && userModel.getLogin().equalsIgnoreCase(me.getLogin()))
|| (parser != null && parser.getLogin().equalsIgnoreCase(me.getLogin()));
}
@Override public boolean isRepoOwner() {
if (getIssue() == null) return false;
Login me = Login.getUser();
return TextUtils.equals(login, me.getLogin());
}
@Override public boolean isLocked() {
return getIssue() != null && getIssue().isLocked();
}
@Override public boolean isCollaborator() {
return isCollaborator;
}
@Override public boolean showToRepoBtn() {
return showToRepoBtn;
}
@Override public void onHandleConfirmDialog(@Nullable Bundle bundle) {
if (bundle != null) {
boolean proceedCloseIssue = bundle.getBoolean(BundleConstant.EXTRA);
boolean proceedLockUnlock = bundle.getBoolean(BundleConstant.EXTRA_TWO);
if (proceedCloseIssue) {
onOpenCloseIssue();
} else if (proceedLockUnlock) {
onLockUnlockIssue();
}
}
}
@Override public void onOpenCloseIssue() {
Issue currentIssue = getIssue();
if (currentIssue != null) {
IssueRequestModel requestModel = IssueRequestModel.clone(currentIssue, true);
manageSubscription(RxHelper.getObserver(RestProvider.getIssueService().editIssue(login, repoId,
issueNumber, requestModel))
.doOnSubscribe(() -> sendToView(view -> view.showProgress(0)))
.doOnNext(issue -> {
if (issue != null) {
sendToView(view -> view.showSuccessIssueActionMsg(currentIssue.getState() == IssueState.open));
issue.setRepoId(issueModel.getRepoId());
issue.setLogin(issueModel.getLogin());
issueModel = issue;
sendToView(IssuePagerMvp.View::onSetupIssue);
}
})
.onErrorReturn(throwable -> {
sendToView(view -> view.showErrorIssueActionMsg(currentIssue.getState() == IssueState.open));
return null;
})
.subscribe());
}
}
@Override public void onLockUnlockIssue() {
Issue currentIssue = getIssue();
if (currentIssue == null) return;
String login = currentIssue.getUser().getLogin();
String repoId = currentIssue.getRepoId();
int number = currentIssue.getNumber();
IssueService issueService = RestProvider.getIssueService();
Observable<Response<Boolean>> observable = RxHelper
.getObserver(isLocked() ? issueService.unlockIssue(login, repoId, number) : issueService.lockIssue(login, repoId, number));
makeRestCall(observable, booleanResponse -> {
int code = booleanResponse.code();
if (code == 204) {
issueModel.setLocked(!isLocked());
sendToView(IssuePagerMvp.View::onSetupIssue);
}
sendToView(IssuePagerMvp.View::hideProgress);
});
}
@Override public void onLoadLabels() {
manageSubscription(
RxHelper.getObserver(RestProvider.getRepoService().getLabels(login, repoId))
.doOnSubscribe(this::onSubscribed)
.doOnNext(response -> {
if (response.getItems() != null && !response.getItems().isEmpty()) {
sendToView(view -> view.onLabelsRetrieved(response.getItems()));
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
}
})
.onErrorReturn(throwable -> {
sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
return null;
})
.subscribe()
);
}
@Override public void onPutMilestones(@NonNull MilestoneModel milestone) {
issueModel.setMilestone(milestone);
IssueRequestModel issueRequestModel = IssueRequestModel.clone(issueModel, false);
makeRestCall(RestProvider.getIssueService().editIssue(login, repoId, issueNumber, issueRequestModel),
issue -> {
this.issueModel = issue;
issueModel.setLogin(login);
issueModel.setRepoId(repoId);
manageSubscription(issue.save(issueModel).subscribe());
sendToView(IssuePagerMvp.View::onUpdateTimeline);
});
}
@Override public void onPutLabels(@NonNull ArrayList<LabelModel> labels) {
makeRestCall(RestProvider.getIssueService().putLabels(login, repoId, issueNumber,
Stream.of(labels).filter(value -> value != null && value.getName() != null)
.map(LabelModel::getName).collect(Collectors.toList())),
labelModels -> {
sendToView(IssuePagerMvp.View::onUpdateTimeline);
LabelListModel listModel = new LabelListModel();
listModel.addAll(labels);
issueModel.setLabels(listModel);
manageSubscription(issueModel.save(issueModel).subscribe());
});
}
@Override public void onPutAssignees(@NonNull ArrayList<User> users) {
AssigneesRequestModel assigneesRequestModel = new AssigneesRequestModel();
ArrayList<String> assignees = new ArrayList<>();
Stream.of(users).forEach(userModel -> assignees.add(userModel.getLogin()));
assigneesRequestModel.setAssignees(assignees);
makeRestCall(RestProvider.getIssueService().putAssignees(login, repoId, issueNumber, assigneesRequestModel),
issue -> {
this.issueModel = issue;
issueModel.setLogin(login);
issueModel.setRepoId(repoId);
UsersListModel assignee = new UsersListModel();
assignee.addAll(users);
issueModel.setAssignees(assignee);
manageSubscription(issueModel.save(issueModel).subscribe());
sendToView(IssuePagerMvp.View::onUpdateTimeline);
}
);
}
@Override public String getLogin() {
return login;
}
@Override public String getRepoId() {
return repoId;
}
@Override public void onUpdateIssue(@NonNull Issue issue) {
this.issueModel = issue;
this.issueModel.setLogin(login);
this.issueModel.setRepoId(repoId);
manageSubscription(issueModel.save(issueModel).subscribe());
sendToView(IssuePagerMvp.View::onSetupIssue);
}
@Override public void onSubscribeOrMute(boolean mute) {
if (getIssue() == null) return;
String url = NotificationService.SUBSCRIPTION_URL;
String utf = NotificationService.UTF8;
String issue = NotificationService.ISSUE_THREAD_CLASS;
String token = PrefGetter.getToken();
String id = mute ? NotificationService.MUTE : NotificationService.SUBSCRIBE;
makeRestCall(AbstractRepo.getRepo(repoId, login)
.flatMap(repo -> RestProvider.getNotificationService()
.subscribe(url, repo.getId(), getIssue().getId(), issue, id, token, utf)),
booleanResponse -> {
if (booleanResponse.code() == 204 || booleanResponse.code() == 200) {
sendToView(view -> view.showMessage(R.string.success, R.string.successfully_submitted));
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.network_error));
}
});
}
}