package hudson.plugins.cigame;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import hudson.model.AbstractBuild;
import hudson.plugins.cigame.model.ScoreHistoryEntry;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import hudson.model.User;
import hudson.model.UserProperty;
import java.util.Collections;
import java.util.List;
/**
*
* @author Erik Ramfelt
*/
@ExportedBean(defaultVisibility = 999)
public class UserScoreProperty extends UserProperty {
@VisibleForTesting
protected static final int MAX_HISTORY_LENGTH = 10;
private double score;
/** Inversed name as default value is false when serializing from data that
* has doesnt have the value. */
private boolean isNotParticipatingInGame;
private List<ScoreHistoryEntry> scoreHistoryEntries;
public UserScoreProperty() {
score = 0;
isNotParticipatingInGame = false;
}
@DataBoundConstructor
public UserScoreProperty(double score, boolean participatingInGame, List<ScoreHistoryEntry> scoreHistoryEntries) {
this.score = score;
this.isNotParticipatingInGame = !participatingInGame;
this.scoreHistoryEntries = scoreHistoryEntries != null ? Lists.newLinkedList(scoreHistoryEntries) : null;
}
@Exported
public User getUser() {
return user;
}
@Exported
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Exported
public boolean isParticipatingInGame() {
return !isNotParticipatingInGame;
}
public void rememberAccountableBuilds(List<AbstractBuild<?, ?>> accountableBuilds, double score) {
this.addScoreHistoryEntry(ScoreHistoryEntry.fromScoreAward(accountableBuilds, score));
}
@VisibleForTesting
protected void addScoreHistoryEntry(ScoreHistoryEntry scoreHistoryEntry) {
if(this.scoreHistoryEntries == null) {
this.scoreHistoryEntries = Lists.newLinkedList();
}
makeSpaceForNewEntryInHistory();
this.scoreHistoryEntries.add(0, scoreHistoryEntry);
}
private void makeSpaceForNewEntryInHistory() {
while(historyReachesOrIsAboveCapacityLimit()) {
removeOldestHistoryEntry();
}
}
private void removeOldestHistoryEntry() {
this.scoreHistoryEntries.remove(this.scoreHistoryEntries.size()-1);
}
private boolean historyReachesOrIsAboveCapacityLimit() {
return this.scoreHistoryEntries.size() >= MAX_HISTORY_LENGTH;
}
@Exported
public List<ScoreHistoryEntry> getMostRecentScores() {
if(this.scoreHistoryEntries == null) {
return Collections.emptyList();
}
return Lists.newLinkedList(this.scoreHistoryEntries);
}
@Override
public String toString() {
return String.format("UserScoreProperty [isNotParticipatingInGame=%s, score=%s, user=%s, scoreHistory=%s]", isNotParticipatingInGame, score, user, scoreHistoryEntries); //$NON-NLS-1$
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (isNotParticipatingInGame ? 1231 : 1237);
long temp;
temp = Double.doubleToLongBits(score);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + scoreHistoryEntries.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof UserScoreProperty))
return false;
UserScoreProperty other = (UserScoreProperty) obj;
if (isNotParticipatingInGame != other.isNotParticipatingInGame)
return false;
if (Double.doubleToLongBits(score) != Double.doubleToLongBits(other.score))
return false;
if (!Objects.equal(this.scoreHistoryEntries, other.scoreHistoryEntries))
return false;
return true;
}
}