package com.sap.pto.services; import java.util.Arrays; import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.apache.commons.lang3.StringUtils; import com.sap.pto.dao.FixtureDAO; import com.sap.pto.dao.LeagueDAO; import com.sap.pto.dao.PredictionDAO; import com.sap.pto.dao.entities.Fixture; import com.sap.pto.dao.entities.League; import com.sap.pto.dao.entities.LeagueMember; import com.sap.pto.dao.entities.Prediction; import com.sap.pto.dao.entities.User; import com.sap.pto.dao.entities.UserStatistics; import com.sap.pto.dao.entities.Fixture.Result; import com.sap.pto.paul.AveragePaul; import com.sap.pto.util.UserUtil; @Path("/leagueservice") public class LeagueService extends BasicService { @POST @Path("/leagues") @Consumes(MediaType.APPLICATION_JSON) public Response createLeague(League league) { User user = userUtil.getLoggedInUser(request); league.setName(sanitize(league.getName())); if (StringUtils.isBlank(league.getName())) { throwBadRequest("Name must be supplied."); } List<League> leagues = LeagueDAO.getForOwner(user); for (League existingLeague : leagues) { if (existingLeague.getName().equalsIgnoreCase(league.getName())) { throwError(Status.CONFLICT, "League with that name already exists."); } } // copy settings so that user cannot create a league for someone else League newLeague = new League(user, league.getName()); LeagueDAO.saveNew(newLeague); // join joinLeague(newLeague.getAccessKey()); // smuggle in Paul into every league User paul = UserUtil.getPaul(); newLeague = LeagueDAO.getLeagueByKey(newLeague.getAccessKey()); newLeague.getMembers().add(new LeagueMember(paul)); newLeague = LeagueDAO.save(newLeague); return Response.ok(newLeague).build(); } @GET @Path("/leagues/{id}") @Produces(MediaType.APPLICATION_JSON) public League getLeague(@PathParam("id") long id) { User user = userUtil.getLoggedInUser(request); League league = new LeagueDAO().getById(id); if (league == null) { throwBadRequest(); } if (!league.getUsers().contains(user)) { throwUnauthorized(); } for (LeagueMember member : league.getMembers()) { UserStatistics stats = new UserStatistics(member.getUser()); member.setStatistics(stats); } return league; } @GET @Path("/leagues/{id}/{fixtureid}") @Produces(MediaType.APPLICATION_JSON) public League getLeague(@PathParam("id") long id, @PathParam("fixtureid") long fixtureId) { User user = userUtil.getLoggedInUser(request); League league = getLeague(id); Fixture fixture = new FixtureDAO().getById(fixtureId); if (fixture == null) { throwNotFound("Fixture could not be found."); } // check if league members predicted the game and return their predictions List<Prediction> predictions = PredictionDAO.getPastForFixture(fixture); // FIXME: inefficient for many users, actually only pull those predictions of the league members AveragePaul.predictMissingFixtures(Arrays.asList(fixture), predictions); for (Prediction prediction : predictions) { for (LeagueMember member : league.getMembers()) { if (prediction.getUser().equals(member.getUser())) { if (prediction.getUser().equals(user) || fixture.getResult() != Result.NONE) { member.setPrediction(prediction); } } } } return league; } @POST @Path("/join/{key}") @Produces(MediaType.APPLICATION_JSON) public Response joinLeague(@PathParam("key") String key) { League league = LeagueDAO.getLeagueByKey(key); if (league == null) { throwBadRequest("League could not be found."); } User user = userUtil.getLoggedInUser(request); // don't allow to join twice for (LeagueMember member : league.getMembers()) { if (member.getUser().equals(user)) { throwError(Status.CONFLICT, "User is already a league member."); } } league.getMembers().add(new LeagueMember(user)); league = LeagueDAO.save(league); return RESPONSE_OK; } @POST @Path("/leagues/{id}/leave") @Produces(MediaType.APPLICATION_JSON) public Response leaveLeague(@PathParam("id") long leagueId) { League league = new LeagueDAO().getById(leagueId); if (league == null) { throwBadRequest("League could not be found."); } User user = userUtil.getLoggedInUser(request); for (Iterator<LeagueMember> iterator = league.getMembers().iterator(); iterator.hasNext();) { LeagueMember member = iterator.next(); if (member.getUser().equals(user)) { iterator.remove(); league = LeagueDAO.save(league); // delete league if only bots are left // FIXME: will not work if second bot comes into play if (league.getMembers().size() == 1) { league.getMembers().clear(); league = LeagueDAO.save(league); } if (league.getMembers().size() == 0) { new LeagueDAO().deleteById(league.getId()); } return RESPONSE_OK; } } return RESPONSE_BAD; } @DELETE @Path("/leagues/{id}") @Produces(MediaType.APPLICATION_JSON) public Response deleteLeague(@PathParam("id") long leagueId) { League league = new LeagueDAO().getById(leagueId); if (league == null) { throwBadRequest("League could not be found."); } User user = userUtil.getLoggedInUser(request); if (!league.getOwner().equals(user)) { throwUnauthorized("Only the league owner can delete a league."); } // TODO: implement return RESPONSE_OK; } @GET @Path("/leagues") @Produces(MediaType.APPLICATION_JSON) public List<League> getUserLeagues() { User user = userUtil.getLoggedInUser(request); List<League> leagues = LeagueDAO.getForUser(user); return leagues; } }