package com.hubspot.blazar.resources;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.StreamingOutput;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.io.Resources;
import com.hubspot.blazar.base.ModuleState;
import com.hubspot.blazar.base.RepositoryBuild;
import com.hubspot.blazar.base.RepositoryState;
import com.hubspot.blazar.base.branch.BranchStatus;
import com.hubspot.blazar.cctray.CCTrayProject;
import com.hubspot.blazar.cctray.CCTrayProjectFactory;
import com.hubspot.blazar.cctray.CCTrayWrapper;
import com.hubspot.blazar.data.cache.StateCache;
import com.hubspot.blazar.data.service.BranchStatusService;
import com.hubspot.blazar.data.service.StateService;
import com.hubspot.jackson.jaxrs.PropertyFiltering;
@Path("/branches/state")
@Produces(MediaType.APPLICATION_JSON)
public class BranchStateResource {
private final StateService stateService;
private BranchStatusService branchStatusService;
private final StateCache stateCache;
private final CCTrayProjectFactory ccTrayProjectFactory;
@Inject
public BranchStateResource(StateService stateService,
BranchStatusService branchStatusService,
StateCache stateCache,
CCTrayProjectFactory ccTrayProjectFactory) {
this.stateService = stateService;
this.branchStatusService = branchStatusService;
this.stateCache = stateCache;
this.ccTrayProjectFactory = ccTrayProjectFactory;
}
@GET
@PropertyFiltering
public Set<RepositoryState> getAll() {
return stateCache.getAllRepositoryStates();
}
@GET
@Path("/cc.xml")
@Produces(MediaType.APPLICATION_XML)
public CCTrayWrapper getCCTrayXml() {
Set<CCTrayProject> projects = new HashSet<>();
for (RepositoryState repositoryState : getAll()) {
Optional<CCTrayProject> maybeProject = ccTrayProjectFactory.apply(repositoryState);
if (maybeProject != null && maybeProject.isPresent()) {
projects.add(maybeProject.get());
}
}
return new CCTrayWrapper(projects);
}
@GET
@Path("/{branchId}")
@PropertyFiltering
public Optional<RepositoryState> get(@PathParam("branchId") int branchId) {
return stateService.getRepositoryState(branchId);
}
@GET
@Path("/{branchId}/modules")
@PropertyFiltering
public Set<ModuleState> getAllModuleStatesForBranch(@PathParam("branchId") int branchId) {
Optional<BranchStatus> status = branchStatusService.getBranchStatusById(branchId);
if (status.isPresent()) {
return status.get().getModuleStates();
} else {
return ImmutableSet.of();
}
}
@GET
@Path("/{branchId}/shield")
@Produces("image/svg+xml")
public StreamingOutput getShield(@PathParam("branchId") int branchId) {
Optional<RepositoryState> state = stateService.getRepositoryState(branchId);
if (!state.isPresent()) {
throw new IllegalArgumentException(String.format("No state for id %d", branchId));
}
final String path;
if (state.get().getLastBuild().isPresent()) {
path = pickImage(state.get().getLastBuild().get().getState());
} else {
path = "shields/build-???-lightgrey.svg";
}
return new StreamingOutput() {
@Override
public void write(OutputStream outputStream) throws IOException, WebApplicationException {
ByteStreams.copy(Resources.getResource(path).openStream(), outputStream);
}
};
}
private static String pickImage(RepositoryBuild.State state) {
switch (state) {
case FAILED:
return "shields/build-failing-red.svg";
case SUCCEEDED:
return "shields/build-passing-green.svg";
case CANCELLED:
return "shields/build-cancelled-yellow.svg";
case UNSTABLE:
return "shields/build-unstable-red.svg";
default:
return "shields/build-???-lightgrey.svg";
}
}
}