package slacknotifications.teamcity;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static slacknotifications.teamcity.BuildStateEnum.*;
public class BuildState {
Map<BuildStateEnum, BuildStateInterface> states = new HashMap<BuildStateEnum, BuildStateInterface>();
public BuildState() {
states.clear();
states.put(BuildStateEnum.BUILD_STARTED, new SimpleBuildState(BuildStateEnum.BUILD_STARTED, false));
//states.put(BuildStateEnum.BUILD_CHANGED_STATUS, new SimpleBuildState(BuildStateEnum.BUILD_CHANGED_STATUS, false));
states.put(BuildStateEnum.BEFORE_BUILD_FINISHED, new SimpleBuildState(BuildStateEnum.BEFORE_BUILD_FINISHED, false));
states.put(BuildStateEnum.RESPONSIBILITY_CHANGED, new SimpleBuildState(BuildStateEnum.RESPONSIBILITY_CHANGED, false));
states.put(BuildStateEnum.BUILD_INTERRUPTED, new SimpleBuildState(BuildStateEnum.BUILD_INTERRUPTED, false));
states.put(BuildStateEnum.BUILD_SUCCESSFUL, new SimpleBuildState(BuildStateEnum.BUILD_SUCCESSFUL, false));
states.put(BuildStateEnum.BUILD_FAILED, new SimpleBuildState(BuildStateEnum.BUILD_FAILED, false));
states.put(BuildStateEnum.BUILD_BROKEN, new SimpleBuildState(BuildStateEnum.BUILD_BROKEN, false));
states.put(BuildStateEnum.BUILD_FIXED, new SimpleBuildState(BuildStateEnum.BUILD_FIXED, false));
states.put(BuildStateEnum.BUILD_FINISHED, new SimpleBuildState(BuildStateEnum.BUILD_FINISHED, false));
}
public Set<BuildStateEnum> getStateSet(){
return states.keySet();
}
/**
* Takes the currentBuildState, for which the SlackNotification is being triggered
* and compares it against the build states for which this SlackNotification is configured
* to notify.
*
* @param currentBuildState
* @param buildStatesToNotify
* @return Whether or not the slacknotifications should trigger for the current build state.
*/
public boolean enabled(BuildStateEnum currentBuildState) {
return states.get(currentBuildState).isEnabled();
}
public boolean enabled(BuildStateEnum currentBuildState, boolean success, boolean changed){
if (currentBuildState != BuildStateEnum.BUILD_FINISHED){
return enabled(currentBuildState);
} else {
if (enabled(BUILD_SUCCESSFUL) && enabled(BUILD_FIXED) && changed && success){
return true;
}
if (enabled(BUILD_SUCCESSFUL) && !enabled(BUILD_FIXED) && success){
return true;
}
if (enabled(BUILD_FAILED) && enabled(BUILD_BROKEN) && changed && !success){
return true;
}
if (enabled(BUILD_FAILED) && !enabled(BUILD_BROKEN) && !success){
return true;
}
}
return false;
}
public void setEnabled(BuildStateEnum currentBuildState, boolean enabled){
if (enabled)
enable(currentBuildState);
else
disable(currentBuildState);
}
/**
* Enable all build events for notification
* Note: BROKEN and FIXED restrict builds, so don't set those.
*/
public BuildState setAllEnabled(){
for (BuildStateEnum state : states.keySet()){
switch (state){
case BUILD_BROKEN:
disable(state);
break;
case BUILD_FIXED:
disable(state);
break;
default:
enable(state);
break;
}
}
return this;
}
public void enable(BuildStateEnum currentBuildState){
states.get(currentBuildState).enable();
}
public void disable(BuildStateEnum currentBuildState){
states.get(currentBuildState).disable();
}
/**
* Convert build state Integer into short string
*
* @param Build state as an Integer constant.
* @return A string representing the shortname of the state. Is used in messages.
*/
public String getShortName(BuildStateEnum state) {
return state.getShortName();
}
/**
* Convert build state Integer into descriptive string
*
* @param Build state as an Integer constant.
* @return A string that fits into the sentence "The build has...<state>"
*/
public String getDescriptionSuffix(BuildStateEnum state) {
return state.getDescriptionSuffix();
}
public boolean allEnabled() {
boolean areAllEnbled = true;
for (BuildStateEnum state : states.keySet()){
if ((state.equals(BUILD_BROKEN) && states.get(BUILD_BROKEN).isEnabled()) || (state.equals(BUILD_FIXED) && states.get(BUILD_FIXED).isEnabled())){
return false;
}
if (state.equals(BUILD_BROKEN) || state.equals(BUILD_FIXED)) {
continue;
}
areAllEnbled = areAllEnbled && states.get(state).isEnabled();
}
return areAllEnbled;
}
public boolean noneEnabled() {
int enabled = 0;
for (BuildStateEnum state : states.keySet()){
if (state.equals(BUILD_FINISHED)){
if (finishEnabled()){
enabled++;
}
}
if (state.equals(BUILD_FINISHED) || state.equals(BUILD_BROKEN) || state.equals(BUILD_FIXED) || state.equals(BUILD_SUCCESSFUL) || state.equals(BUILD_FAILED)){
continue;
}
if (states.get(state).isEnabled()){
enabled++;
}
}
return enabled == 0;
}
private boolean finishEnabled(){
// If finished is disabled, who cares what the other finish states are set to.
if (! states.get(BUILD_FINISHED).isEnabled()){
return false;
}
// If it's enabled, check its sub-settings.
return (states.get(BUILD_FAILED).isEnabled() || states.get(BUILD_SUCCESSFUL).isEnabled());
}
}