package com.alorma.github.sdk.services.issues.story;
import com.alorma.github.sdk.bean.dto.response.Issue;
import com.alorma.github.sdk.bean.info.IssueInfo;
import com.alorma.github.sdk.bean.issue.IssueEvent;
import com.alorma.github.sdk.bean.issue.IssueStory;
import com.alorma.github.sdk.bean.issue.IssueStoryComment;
import com.alorma.github.sdk.bean.issue.IssueStoryComparators;
import com.alorma.github.sdk.bean.issue.IssueStoryDetail;
import com.alorma.github.sdk.bean.issue.IssueStoryEvent;
import com.alorma.github.sdk.services.client.BaseInfiniteCallback;
import com.alorma.github.sdk.services.client.GithubClient;
import core.GithubComment;
import java.util.Collections;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import retrofit.RestAdapter;
import rx.Observable;
import rx.functions.Func1;
public class IssueStoryLoader extends GithubClient<IssueStory> {
private final IssueInfo issueInfo;
private final String owner;
private final String repo;
private final int num;
private IssueStoryService issueStoryService;
public IssueStoryLoader(IssueInfo info) {
super();
this.issueInfo = info;
this.owner = issueInfo.repoInfo.owner;
this.repo = issueInfo.repoInfo.name;
this.num = issueInfo.num;
issueStoryService = getRestAdapter().create(IssueStoryService.class);
}
@Override
protected Observable<IssueStory> getApiObservable(RestAdapter restAdapter) {
return getIssueStory();
}
private Observable<IssueStory> getIssueStory() {
return Observable.zip(getIssueObservable(), getIssueDetailsObservable(), (issue, details) -> {
IssueStory issueStory = new IssueStory();
issueStory.item = issue;
issueStory.details = details;
Collections.sort(issueStory.details, IssueStoryComparators.ISSUE_STORY_DETAIL_COMPARATOR);
return issueStory;
});
}
private Observable<Issue> getIssueObservable() {
return issueStoryService.detailObs(owner, repo, num).map(new GithubReactionsIssueMapper());
}
private Observable<List<IssueStoryDetail>> getIssueDetailsObservable() {
Observable<IssueStoryDetail> commentsDetailsObs = getCommentsDetailsObs();
Observable<IssueStoryDetail> eventDetailsObs = getEventDetailsObs();
return Observable.mergeDelayError(commentsDetailsObs, eventDetailsObs).toList();
}
private Observable<List<GithubComment>> getCommentsObs() {
return Observable.create(new BaseInfiniteCallback<List<GithubComment>>() {
@Override
public void execute() {
issueStoryService.comments(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, this);
}
@Override
protected void executePaginated(int nextPage) {
issueStoryService.comments(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, nextPage, this);
}
});
}
private Observable<IssueStoryDetail> getCommentsDetailsObs() {
return getCommentsObs().flatMap(githubComments -> Observable.from(githubComments)
.map(new GithubCommentReactionsIssueMapper())
.map((Func1<GithubComment, IssueStoryDetail>) githubComment -> {
long time = getMilisFromDateClearDay(githubComment.created_at);
IssueStoryComment detail = new IssueStoryComment(githubComment);
detail.created_at = time;
return detail;
}));
}
private Observable<List<IssueEvent>> getEventsObs() {
return Observable.create(new BaseInfiniteCallback<List<IssueEvent>>() {
@Override
public void execute() {
issueStoryService.events(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, this);
}
@Override
protected void executePaginated(int nextPage) {
issueStoryService.events(issueInfo.repoInfo.owner, issueInfo.repoInfo.name, issueInfo.num, nextPage, this);
}
});
}
private Observable<IssueStoryDetail> getEventDetailsObs() {
return getEventsObs().flatMap(issueEvents -> Observable.from(issueEvents)
.filter(issueEvent -> validEvent(issueEvent.event))
.map((Func1<IssueEvent, IssueStoryDetail>) issueEvent -> {
long time = getMilisFromDateClearDay(issueEvent.created_at);
IssueStoryEvent detail = new IssueStoryEvent(issueEvent);
detail.created_at = time;
return detail;
}));
}
private long getMilisFromDateClearDay(String createdAt) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
DateTime dt = formatter.parseDateTime(createdAt);
return dt.minuteOfDay().roundFloorCopy().getMillis();
}
private boolean validEvent(String event) {
return !(event.equals("mentioned") ||
event.equals("subscribed") ||
event.equals("unsubscribed") ||
event.equals("labeled") ||
event.equals("unlabeled"));
}
@Override
public String getAcceptHeader() {
return "application/vnd.github.v3.full+json";
}
}