package engine;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.servlet.ServletContext;
import dao.DaoPassageTrainTheorique;
import externaldata.gare.Gare;
import externaldata.passageTrainReel.PackPassageTrainReel;
import externaldata.passageTrainReel.PassageTrainReel;
import externaldata.passageTrainReel.PassageTrainReelHelper;
import externaldata.passageTrainTheorique.PassageTrainTheorique;
import externaldata.passageTrainTheorique.PassageTrainTheoriqueLive;
/**
* Thread chargé de récupérer les horaires réels des trains d'une station
* et de les comparer avec ceux théoriques stockés en BDD.
* Si besoin, ce thread devra mettre à jour les paris faits par les utilisateurs.
*/
public class StationTask implements Runnable {
private Gare gare;
private PackPassageTrainReel trainsActuels;
private ServletContext context;
public StationTask(Gare gare, ServletContext context) {
this.gare = gare;
this.context = context;
}
@Override
public void run() {
trainsActuels = null;
try {
trainsActuels = PassageTrainReelHelper.getDataFromAPI(gare.getUic());
} catch (Exception e) {
e.printStackTrace();
}
if (trainsActuels != null) {
@SuppressWarnings("unchecked")
Map<String, List<PassageTrainTheoriqueLive>> parisDansContexte =
((Map<String, List<PassageTrainTheoriqueLive>>) context.getAttribute("paris_disponibles"));
List<PassageTrainTheoriqueLive> tmpNewListeParisDispos =
new Vector<PassageTrainTheoriqueLive>(parisDansContexte.get(gare.getDua()));
// Mise à jour des PTTL en fonction des données récupérées dans l'API temps réel
for (PassageTrainReel passageReel : trainsActuels.passagesList) {
String numTrain = passageReel.getNumeroTrain();
PassageTrainTheorique passageTheoriqueCorrespondant =
DaoPassageTrainTheorique.getOne(numTrain, gare.getDua(), passageReel.getArriveeGare());
// Test du numTrain -1 (dépend du sens du train), voir explication sur :
// http://data.sncf.com/forum/le-programme-sncf-open-data/topics/liste-gare-desservis-par-un-train
if (passageTheoriqueCorrespondant == null) {
numTrain = String.format("%06d", (Integer.parseInt(numTrain) - 1));
passageTheoriqueCorrespondant = DaoPassageTrainTheorique.getOne(numTrain, gare.getDua(), passageReel.getArriveeGare());
}
if (passageTheoriqueCorrespondant != null) {
PassageTrainTheoriqueLive passageTheoriqueCorrespondantLive = null;
// Si le PTT est déjà dans la liste des paris dispos
for (PassageTrainTheoriqueLive pttl : tmpNewListeParisDispos) {
if (pttl.equals(passageTheoriqueCorrespondant)) {
passageTheoriqueCorrespondantLive = pttl;
break;
}
}
// Si le PTT est nouveau et doit être ajouté à la liste des paris dispos
if (passageTheoriqueCorrespondantLive == null) {
passageTheoriqueCorrespondantLive = new PassageTrainTheoriqueLive(passageTheoriqueCorrespondant);
tmpNewListeParisDispos.add(passageTheoriqueCorrespondantLive);
}
// Maj des données "live"
passageTheoriqueCorrespondantLive.setArriveeReelleEnGare(passageReel.getArriveeGare());
if ((passageTheoriqueCorrespondantLive.getArriveeReelleEnGare().getTime()
- trainsActuels.dateHeureRequeteHttp.getTime()) >= 15*60*1000) {
passageTheoriqueCorrespondantLive.setPourraitEtreAnnule(true);
}
else {
passageTheoriqueCorrespondantLive.setPourraitEtreAnnule(false);
}
// Maj des données "PTT"
passageTheoriqueCorrespondantLive.setDestinationUic(passageReel.getDestinationUic());
DaoPassageTrainTheorique.updateOne(passageTheoriqueCorrespondantLive);
}
}
List<PassageTrainTheoriqueLive> newListeParisDispos =
new Vector<PassageTrainTheoriqueLive>(tmpNewListeParisDispos);
// Parcourt de la liste des paris dispos qui vient d'être mise à jour
for (PassageTrainTheoriqueLive pttl : tmpNewListeParisDispos) {
// Pari encore possible sur ce train ?
if ((pttl.getArriveeReelleEnGare().getTime() - trainsActuels.dateHeureRequeteHttp.getTime()) >= 10*60*1000) {
pttl.setPariAutorise(true);
}
else {
pttl.setPariAutorise(false);
}
// Train passe en gare selon les dernières infos reçues de l'API temps réel
if (pttl.getArriveeReelleEnGare().getTime() == trainsActuels.dateHeureRequeteHttp.getTime()) {
if (pttl.getPourraitEtreAnnule()) {
// Train annulé (ou retard incalculable car données trop anciennes)
DaoPassageTrainTheorique.deleteOne(pttl);
}
else {
// Train bien en gare
long retardSecondes = (pttl.getArriveeReelleEnGare().getTime()
- pttl.getArriveeTheorique().getTime()) / 1000;
DaoPassageTrainTheorique.validerTrainEnGare(pttl, (int)retardSecondes / 60);
}
newListeParisDispos.remove(pttl);
}
}
// On valide les défis qui portent sur les éventuels paris des trains qui sont passés en gare
DaoPassageTrainTheorique.validerDefis();
/*
for (PassageTrainTheoriqueLive pttl : newListeParisDispos) {
System.out.println("Pari possible : ");
System.out.println("\tNum train : " + pttl.getNumeroTrain());
System.out.println("\tNom train : " + pttl.getNomTrain());
System.out.println("\tRéseau train : " + pttl.getReseauTrain());
System.out.println("\tGare de passage : " + pttl.getGareDua());
System.out.println("\tHeure de passage théorique : " + pttl.getArriveeTheorique().toString());
System.out.println("\tHeure de passage réelle prévue : " + pttl.getArriveeReelleEnGare().toString());
System.out.println("\tPari encore autorisé dessus : " + pttl.getPariAutorise());
System.out.println("\tDonnées potentiellement périmées (plus de 15 minutes) : " + pttl.getPourraitEtreAnnule());
}
*/
// On met la nouvelle liste de paris dispos dans le contexte
parisDansContexte.put(gare.getDua(), newListeParisDispos);
System.out.println("Fin d'update train temps réel.");
}
}
}