package com.fastaccess.data.dao.model;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import com.fastaccess.App;
import com.fastaccess.R;
import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UsersListModel;
import com.fastaccess.data.dao.converters.CommitConverter;
import com.fastaccess.data.dao.converters.LabelsListConverter;
import com.fastaccess.data.dao.converters.MilestoneConverter;
import com.fastaccess.data.dao.converters.PullRequestConverter;
import com.fastaccess.data.dao.converters.ReactionsConverter;
import com.fastaccess.data.dao.converters.UserConverter;
import com.fastaccess.data.dao.converters.UsersConverter;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.helper.RxHelper;
import com.fastaccess.ui.widgets.SpannableBuilder;
import java.util.Date;
import java.util.List;
import io.requery.Column;
import io.requery.Convert;
import io.requery.Entity;
import io.requery.Key;
import io.requery.Persistable;
import io.requery.rx.SingleEntityStore;
import lombok.NoArgsConstructor;
import rx.Observable;
import rx.Single;
import static com.fastaccess.data.dao.model.PullRequest.ID;
import static com.fastaccess.data.dao.model.PullRequest.LOGIN;
import static com.fastaccess.data.dao.model.PullRequest.NUMBER;
import static com.fastaccess.data.dao.model.PullRequest.REPO_ID;
import static com.fastaccess.data.dao.model.PullRequest.STATE;
import static com.fastaccess.data.dao.model.PullRequest.UPDATED_AT;
/**
* Created by Kosh on 16 Mar 2017, 7:39 PM
*/
@Entity @NoArgsConstructor public abstract class AbstractPullRequest implements Parcelable {
@Key long id;
String url;
String body;
String title;
int comments;
int number;
boolean locked;
boolean mergable;
boolean merged;
boolean mergeable;
int commits;
int additions;
int deletions;
IssueState state;
String bodyHtml;
String htmlUrl;
Date closedAt;
Date createdAt;
Date updatedAt;
int changedFiles;
String diffUrl;
String patchUrl;
String mergeCommitSha;
Date mergedAt;
String mergeState;
int reviewComments;
String repoId;
String login;
@Convert(UsersConverter.class) UsersListModel assignees;
@Convert(UserConverter.class) User mergedBy;
@Convert(UserConverter.class) User closedBy;
@Column(name = "user_column") @Convert(UserConverter.class) User user;
@Convert(UserConverter.class) User assignee;
@Convert(LabelsListConverter.class) LabelListModel labels;
@Convert(MilestoneConverter.class) MilestoneModel milestone;
@Convert(CommitConverter.class) Commit base;
@Convert(CommitConverter.class) Commit head;
@Convert(PullRequestConverter.class) PullRequest pullRequest;
@Convert(ReactionsConverter.class) ReactionsModel reactions;
public Single save(PullRequest entity) {
return App.getInstance().getDataStore()
.delete(PullRequest.class)
.where(ID.eq(entity.getId()))
.get()
.toSingle()
.flatMap(integer -> App.getInstance().getDataStore().insert(entity));
}
public static Observable save(@NonNull List<PullRequest> models, @NonNull String repoId, @NonNull String login) {
SingleEntityStore<Persistable> singleEntityStore = App.getInstance().getDataStore();
return RxHelper.safeObservable(singleEntityStore.delete(PullRequest.class)
.where(REPO_ID.equal(repoId)
.and(LOGIN.equal(login)))
.get()
.toSingle()
.toObservable()
.flatMap(integer -> Observable.from(models))
.flatMap(pulRequest -> {
pulRequest.setRepoId(repoId);
pulRequest.setLogin(login);
return pulRequest.save(pulRequest).toObservable();
}));
}
public static Observable<List<PullRequest>> getPullRequests(@NonNull String repoId, @NonNull String login,
@NonNull IssueState issueState) {
return App.getInstance().getDataStore()
.select(PullRequest.class)
.where(REPO_ID.equal(repoId)
.and(LOGIN.equal(login))
.and(STATE.equal(issueState)))
.orderBy(UPDATED_AT.desc())
.get()
.toObservable()
.toList();
}
public static Observable<PullRequest> getPullRequestById(long id) {
return App.getInstance().getDataStore()
.select(PullRequest.class)
.where(ID.eq(id))
.get()
.toObservable();
}
public static Observable<PullRequest> getPullRequestByNumber(int number, @NonNull String repoId, @NonNull String login) {
return App.getInstance().getDataStore()
.select(PullRequest.class)
.where(REPO_ID.equal(repoId)
.and(LOGIN.equal(login))
.and(NUMBER.equal(number)))
.get()
.toObservable();
}
@NonNull public static SpannableBuilder getMergeBy(@NonNull PullRequest pullRequest, @NonNull Context context, boolean showRepoName) {
boolean isMerge = pullRequest.isMerged() || !InputHelper.isEmpty(pullRequest.mergedAt);
if (isMerge) {
User merger = pullRequest.getMergedBy();
SpannableBuilder builder = SpannableBuilder.builder();
if (showRepoName) {
PullsIssuesParser parser = PullsIssuesParser.getForPullRequest(pullRequest.getHtmlUrl());
if (parser != null)
builder.bold(parser.getLogin())
.append("/")
.bold(parser.getRepoId())
.append(" ")
.bold("#").bold(String.valueOf(pullRequest.getNumber()))
.append(" ");
} else {
builder.bold("#" + pullRequest.getNumber())
.append(" ")
.append(merger != null ? merger.getLogin() + " " : "");
}
builder.append(context.getString(R.string.merged).toLowerCase())
.append(" ");
if (pullRequest.getHead() != null) {
builder.bold(pullRequest.getHead().getRef())
.append(" ")
.append(context.getString(R.string.to))
.append(" ")
.bold(pullRequest.getBase().getRef())
.append(" ");
}
builder.append(ParseDateFormat.getTimeAgo(pullRequest.getMergedAt()));
return builder;
} else {
User user = pullRequest.getUser();
String status = context.getString(pullRequest.getState().getStatus());
SpannableBuilder builder = SpannableBuilder.builder();
if (showRepoName) {
PullsIssuesParser parser = PullsIssuesParser.getForPullRequest(pullRequest.getHtmlUrl());
if (parser != null) {
builder.bold(parser.getLogin())
.append("/")
.bold(parser.getRepoId())
.append(" ")
.bold("#").bold(String.valueOf(pullRequest.getNumber()))
.append(" ");
}
} else {
builder.bold("#" + pullRequest.getNumber())
.append(" ")
.append(user.getLogin())
.append(" ");
}
if (pullRequest.getState() == IssueState.open && pullRequest.getHead() != null && pullRequest.getBase() != null) {
return builder
.append(context.getString(R.string.want_to_merge))
.append(" ")
.bold(pullRequest.getHead().getRef())
.append(" ")
.append(context.getString(R.string.to))
.append(" ")
.bold(pullRequest.getBase().getRef())
.append(" ")
.append(ParseDateFormat.getTimeAgo(pullRequest.getState() == IssueState.closed
? pullRequest.getClosedAt() : pullRequest.getCreatedAt()));
} else {
return builder
.bold(status.toLowerCase())
.append(" ")
.bold(pullRequest.getHead() != null ? pullRequest.getHead().getRef() : "")
.append(" ")
.append(ParseDateFormat.getTimeAgo(pullRequest.getState() == IssueState.closed
? pullRequest.getClosedAt() : pullRequest.getCreatedAt()));
}
}
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.url);
dest.writeString(this.body);
dest.writeString(this.title);
dest.writeInt(this.comments);
dest.writeInt(this.number);
dest.writeByte(this.locked ? (byte) 1 : (byte) 0);
dest.writeByte(this.mergable ? (byte) 1 : (byte) 0);
dest.writeByte(this.merged ? (byte) 1 : (byte) 0);
dest.writeByte(this.mergeable ? (byte) 1 : (byte) 0);
dest.writeInt(this.commits);
dest.writeInt(this.additions);
dest.writeInt(this.deletions);
dest.writeInt(this.state == null ? -1 : this.state.ordinal());
dest.writeString(this.bodyHtml);
dest.writeString(this.htmlUrl);
dest.writeLong(this.closedAt != null ? this.closedAt.getTime() : -1);
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
dest.writeInt(this.changedFiles);
dest.writeString(this.diffUrl);
dest.writeString(this.patchUrl);
dest.writeString(this.mergeCommitSha);
dest.writeLong(this.mergedAt != null ? this.mergedAt.getTime() : -1);
dest.writeString(this.mergeState);
dest.writeInt(this.reviewComments);
dest.writeString(this.repoId);
dest.writeString(this.login);
dest.writeList(this.assignees);
dest.writeParcelable(this.mergedBy, flags);
dest.writeParcelable(this.closedBy, flags);
dest.writeParcelable(this.user, flags);
dest.writeParcelable(this.assignee, flags);
dest.writeList(this.labels);
dest.writeParcelable(this.milestone, flags);
dest.writeParcelable(this.base, flags);
dest.writeParcelable(this.head, flags);
dest.writeParcelable(this.pullRequest, flags);
dest.writeParcelable(this.reactions, flags);
}
protected AbstractPullRequest(Parcel in) {
this.id = in.readLong();
this.url = in.readString();
this.body = in.readString();
this.title = in.readString();
this.comments = in.readInt();
this.number = in.readInt();
this.locked = in.readByte() != 0;
this.mergable = in.readByte() != 0;
this.merged = in.readByte() != 0;
this.mergeable = in.readByte() != 0;
this.commits = in.readInt();
this.additions = in.readInt();
this.deletions = in.readInt();
int tmpState = in.readInt();
this.state = tmpState == -1 ? null : IssueState.values()[tmpState];
this.bodyHtml = in.readString();
this.htmlUrl = in.readString();
long tmpClosedAt = in.readLong();
this.closedAt = tmpClosedAt == -1 ? null : new Date(tmpClosedAt);
long tmpCreatedAt = in.readLong();
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
long tmpUpdatedAt = in.readLong();
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
this.changedFiles = in.readInt();
this.diffUrl = in.readString();
this.patchUrl = in.readString();
this.mergeCommitSha = in.readString();
long tmpMergedAt = in.readLong();
this.mergedAt = tmpMergedAt == -1 ? null : new Date(tmpMergedAt);
this.mergeState = in.readString();
this.reviewComments = in.readInt();
this.repoId = in.readString();
this.login = in.readString();
this.assignees = new UsersListModel();
in.readList(this.assignees, this.assignees.getClass().getClassLoader());
this.mergedBy = in.readParcelable(User.class.getClassLoader());
this.closedBy = in.readParcelable(User.class.getClassLoader());
this.user = in.readParcelable(User.class.getClassLoader());
this.assignee = in.readParcelable(User.class.getClassLoader());
this.labels = new LabelListModel();
in.readList(this.labels, this.labels.getClass().getClassLoader());
this.milestone = in.readParcelable(MilestoneModel.class.getClassLoader());
this.base = in.readParcelable(Commit.class.getClassLoader());
this.head = in.readParcelable(Commit.class.getClassLoader());
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
this.reactions = in.readParcelable(ReactionsModel.class.getClassLoader());
}
public static final Creator<PullRequest> CREATOR = new Creator<PullRequest>() {
@Override public PullRequest createFromParcel(Parcel source) {return new PullRequest(source);}
@Override public PullRequest[] newArray(int size) {return new PullRequest[size];}
};
}