using System; using System.Threading.Tasks; using System.Threading; using System.Collections.Generic; using System.Text; using System.Net.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using EFB.Models; using EFB.Models.JSON; using EFB.Sessions; using EFB.Controllers.Form; using EFB.Controllers.API; namespace EFB.Controllers { public class RouteController : Controller { private readonly ILogger _logger; public RouteController(ILogger logger) { _logger = logger; } public IActionResult Index() { //Check the user has a valid login UserModel user = HttpContext.Session.GetObject("User"); if (user == null || user.Route != null || user.Token.IsExpired()) { return RedirectToAction("Index", "Home"); } return View(); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View("Error!"); } public async Task New(string departure, string arrival, string cruise) { UserModel user = HttpContext.Session.GetObject("User"); if (!(user == null || user.Token.IsExpired())) {//If the user is still authenticated if (FormAuthenticator.ValidateICAOCode(departure) && FormAuthenticator.ValidateICAOCode(arrival)) {//If the user has entered valid ICAOs uint cruiseAlt; if (uint.TryParse(cruise, out cruiseAlt) && FormAuthenticator.ValidateCruiseAlt(cruiseAlt)) {//If the cruise altitude if within limits. //Submit route request... APIInterface API = new APIInterface(); //Prepare data to be send off with request (route) Dictionary headerData = new Dictionary(); headerData.Add("Authorization", $"Bearer {user.Token.TokenValue}"); RouteRequest routeRequest = new RouteRequest() { departure = departure, destination = arrival, preferredminlevel = cruiseAlt / 1000, preferredmaxlevel = cruiseAlt / 1000, }; StringContent content = new StringContent(JsonConvert.SerializeObject(routeRequest), Encoding.UTF8, "application/json"); //Make initial Route Request var requestRoute = API.Post("https://api.autorouter.aero/v1.0/router", headerData, content); ResponseModel responseRoute = await requestRoute; if (responseRoute.Error == null) {//Update User session and add route ID RouteModel route = new RouteModel() { RouteID = responseRoute.Result.ToString() }; user.Route = route; HttpContext.Session.SetObject("User", user); return await Poll(); } TempData["Error"] = responseRoute.Error; return RedirectToAction("Index", "Route"); } TempData["Error"] = "Invalid Cruise Altitude"; TempData["Departure"] = departure; TempData["Arrival"] = arrival; return RedirectToAction("Index", "Route"); } TempData["Error"] = "Invalid Departure or Arrival ICAO"; return RedirectToAction("Index", "Route"); } return RedirectToAction("Index", "Home"); } public async Task Poll() { if (HttpContext.Session.GetString("User") != null) {//If the user is currently logged in UserModel user = HttpContext.Session.GetObject("User"); if (user.Route != null) {//If the user has a route object (e.g, they have been to the route page) //Make calls to the server to fetch route bool collected = false; int count = 0; string route = ""; APIInterface API = new APIInterface(); Dictionary headerData = new Dictionary(); headerData.Add("Authorization", $"Bearer {user.Token.TokenValue}"); while (collected == false && count <= 5) { //Make Polling Request var pollingRequest = API.Put>($"https://api.autorouter.aero/v1.0/router/{user.Route.RouteID}/longpoll", headerData, null); ResponseModel> responsePoll = await pollingRequest; int routePos = responsePoll.Result.Count - 1; if (responsePoll.Result[routePos].Command == "solution") { collected = true; route = responsePoll.Result[routePos].FlightPlan; break; } Thread.Sleep(5000); count++; } if (collected) { //fill in route string finalRoute = ParseRoute(route); TempData["Error"] = finalRoute; return RedirectToAction("Index", "Route"); } TempData["Error"] = "Unable to get route!"; return RedirectToAction("Index", "Route"); } else { return RedirectToAction("Index", "Route"); } } else { return RedirectToAction("Index", "Route"); } } private string ParseRoute(string route){ TempData["Error"] = route; route.Replace('/', ' '); var routeArr = route.Split(' '); string finalRoute = ""; foreach (var item in routeArr) { var waypoint = item.Split('/')[0]; if (waypoint.Length <= 7 && waypoint.Length >= 3 && !waypoint.Contains('-')) { finalRoute += $"{waypoint} "; if (waypoint.Length == 7 && finalRoute.Length > 8) break; } } return finalRoute; } } }