UniversalRoutingService.java
package com.soen390.backend.service;
import com.soen390.backend.enums.BuildingLocation;
import com.soen390.backend.enums.TransportMode;
import com.soen390.backend.object.IndoorDirectionResponse;
import com.soen390.backend.object.OutdoorDirectionResponse;
import com.soen390.backend.object.ShuttleSchedule;
import com.soen390.backend.object.UniversalDirectionResponse;
import org.springframework.stereotype.Service;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Service
public class UniversalRoutingService {
private final IndoorDirectionService indoorDirectionService;
private final GoogleMapsService googleMapsService;
private final ShuttleScheduleService shuttleScheduleService;
public UniversalRoutingService(IndoorDirectionService indoorDirectionService,
GoogleMapsService googleMapsService,
ShuttleScheduleService shuttleScheduleService) {
this.indoorDirectionService = indoorDirectionService;
this.googleMapsService = googleMapsService;
this.shuttleScheduleService = shuttleScheduleService;
}
private String getBuildingEntranceId(String buildingId) {
if (buildingId == null) return "main-entrance";
if (buildingId.startsWith("H")) return "H1-Maisonneuve-Entry";
if (buildingId.startsWith("CC")) return "CC-Entrance-Exit";
if (buildingId.startsWith("LB")) return "LB2-Emergency-Exit-1";
if (buildingId.startsWith("VE")) return "VE1-Entrance/exit";
if (buildingId.startsWith("VL")) return "VL-101";
if (buildingId.startsWith("MB")) return "MB1-Main-Entrance";
return "main-entrance";
}
private String getBuildingEntranceFloor(String buildingId) {
if (buildingId == null) return "1";
if (buildingId.startsWith("LB")) return "2";
return "1";
}
public UniversalDirectionResponse getCompleteRoute(
String startBuilding, String startRoom, String startFloor,
String endBuilding, String endRoom, String endFloor,
boolean avoidStairs) {
BuildingLocation originLoc = BuildingLocation.fromId(startBuilding);
BuildingLocation destLoc = BuildingLocation.fromId(endBuilding);
String startExitId = getBuildingEntranceId(startBuilding);
String endEntranceId = getBuildingEntranceId(endBuilding);
String startGroundFloor = getBuildingEntranceFloor(startBuilding);
String endGroundFloor = getBuildingEntranceFloor(endBuilding);
IndoorDirectionResponse leg1 = indoorDirectionService.getIndoorDirections(
startBuilding, startRoom, startExitId, startFloor, startGroundFloor, avoidStairs);
boolean sameCampus = originLoc.campus.equals(destLoc.campus);
TransportMode mode = sameCampus ? TransportMode.WALKING : TransportMode.TRANSIT;
OutdoorDirectionResponse leg2 = googleMapsService.getDirections(
originLoc.getDirectionsTarget(), destLoc.getDirectionsTarget(), mode);
String nextShuttle = null;
if (!sameCampus) {
nextShuttle = getNextShuttleTime(originLoc.campus);
}
IndoorDirectionResponse leg3 = indoorDirectionService.getIndoorDirections(
endBuilding, endEntranceId, endRoom, endGroundFloor, endFloor, avoidStairs);
String totalDuration = calculateTotalDuration(leg2.getDuration());
return new UniversalDirectionResponse(leg1, leg2, leg3, nextShuttle, totalDuration);
}
private String getNextShuttleTime(String fromCampus) {
LocalTime now = LocalTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
List<ShuttleSchedule> schedules = shuttleScheduleService.getSchedules();
for (ShuttleSchedule schedule : schedules) {
if (schedule.getCampus().equalsIgnoreCase(fromCampus) && schedule.getDayType().equalsIgnoreCase("weekday")) {
for (String timeStr : schedule.getDepartureTimes()) {
LocalTime shuttleTime = LocalTime.parse(timeStr, formatter);
if (shuttleTime.isAfter(now)) {
return timeStr;
}
}
}
}
return "No more shuttles today";
}
private String calculateTotalDuration(String dur2) {
return "Approx " + dur2 + " + indoor walking time.";
}
}