package nl.connectedit.swiss.domain.entity; import jakarta.persistence.*; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import lombok.Getter; import lombok.Setter; import nl.connectedit.swiss.domain.EventType; import nl.connectedit.swiss.domain.TournamentStatus; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @Entity @Table @Getter @Setter public class Tournament extends AbstractEntity { public Tournament() { initialize(); } @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private LocalDate date; @Enumerated(EnumType.STRING) private TournamentStatus status; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List events; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List tournamentPlayers; private Long maxEvents; @ElementCollection private List costsPerEvent; private Long courts; private Boolean active; public void initialize() { this.events = new ArrayList<>(); this.events.addAll(Event.getBlankEventSet(this)); this.status = TournamentStatus.UPCOMING; } public Event getEventByType(EventType type) { return events .stream() .filter(event -> event.getType().equals(type)) .findFirst() .orElse(null); } public List getRegistrations() { return events .stream() .map(Event::getRegistrations) .flatMap(List::stream) .collect(Collectors.toCollection(ArrayList::new)); } public List getDrawnOutPlayers() { var drawnOutPlayers = new ArrayList(); for (var event : events) { for (var group : event.getGroups()) { for (var round : group.getRounds()) { var drawnOut = round.getDrawnOut(); if (drawnOut != null) { drawnOutPlayers.add(drawnOut.getPlayer1()); if (drawnOut.getPlayer2() != null) { drawnOutPlayers.add(drawnOut.getPlayer2()); } } } } } return drawnOutPlayers; } public boolean hasPlayersDrawnOutMaxOnce() { var drawnOutPlayers = this.getDrawnOutPlayers(); return drawnOutPlayers.size() == new HashSet<>(drawnOutPlayers).size(); } public List getPlayersPlayingOnlyOneEvent() { var playerEvents = new HashMap>(); for (var registration : getRegistrations()) { if (!playerEvents.containsKey(registration.getPlayer())) { playerEvents.put(registration.getPlayer(), new ArrayList<>()); } playerEvents.get(registration.getPlayer()).add(registration.getEvent().getType()); } return playerEvents.entrySet().stream() .filter(entry -> entry.getValue().size() == 1) .map(Map.Entry::getKey) .toList(); } }