using System.Text.Json; using Core.Annotations; using Core.DI; namespace Core.Routers; [Injectable] public class HttpRouter { private readonly IEnumerable _staticRouters; private readonly IEnumerable _dynamicRoutes; public HttpRouter( IEnumerable staticRouters, IEnumerable dynamicRoutes ) { _staticRouters = staticRouters; _dynamicRoutes = dynamicRoutes; } /* protected groupBy(list: T[], keyGetter: (t: T) => string): Map { const map: Map = new Map(); for (const item of list) { const key = keyGetter(item); const collection = map.get(key); if (!collection) { map.set(key, [item]); } else { collection.push(item); } } return map; } */ public string? GetResponse(HttpRequest req, string sessionID, string? body, out object deserializedObject) { var wrapper = new ResponseWrapper(""); var handled = HandleRoute(req, sessionID, wrapper, _staticRouters, false, body, out deserializedObject); if (!handled) { HandleRoute(req, sessionID, wrapper, _dynamicRoutes, true, body, out deserializedObject); } // TODO: Temporary hack to change ItemEventRouter response sessionID binding to what client expects if (wrapper.Output?.Contains("\"profileChanges\":{") ?? false) { wrapper.Output = wrapper.Output.Replace(sessionID, sessionID); } return wrapper.Output; } protected bool HandleRoute( HttpRequest request, string sessionID, ResponseWrapper wrapper, IEnumerable routers, bool dynamic, string? body, out object deserializedObject ) { var url = request.Path.Value; deserializedObject = null; // remove retry from url if (url?.Contains("?retry=") ?? false) { url = url.Split("?retry=")[0]; } var matched = false; foreach (var route in routers) { if (route.CanHandle(url, dynamic)) { if (dynamic) { wrapper.Output = (route as DynamicRouter).HandleDynamic(url, body, sessionID, wrapper.Output) as string; } else { wrapper.Output = (route as StaticRouter).HandleStatic(url, body, sessionID, wrapper.Output) as string; } matched = true; } } return matched; } protected class ResponseWrapper(string? output) { public string? Output { get; set; } = output; } }