//private static ConcurrentDictionary<Type, CommandParamMap> commandParamMaps = new ConcurrentDictionary<Type, CommandParamMap>();


        public static void RegisterDefaultRoutes()
        {
            #region Queues and Commands


            //delegate resolver
            var delegateResolverRoute = new Route();

            //delegateResolverRoute.action = ProcessCommand;

            RegisterRoute("q", "*", delegateResolverRoute);
            RegisterRoute("c", "*", delegateResolverRoute);
            RegisterRoute("s", "*", delegateResolverRoute);
            RegisterRoute("s", "*", delegateResolverRoute);

            #endregion

            #region Legacy Commands
            if (UnityManager.Commands == null)
            {
                throw new Exception("No Commands Loaded");
            }
            var services = UnityManager.Commands.ToList();

            var serviceInsts = new Dictionary <string, ICommandBase>();

            foreach (var service in services)
            {
                if (serviceInsts.ContainsKey(service.CommandName.ToLower()))
                {
                    continue;
                    //if (!service.GetType().ToString().Contains(".Core.")) serviceInsts[service.CommandName.ToLower()] = service;
                }
                else
                {
                    serviceInsts.Add(service.CommandName.ToLower(), service);
                }
            }

            commands = serviceInsts;

            foreach (var command in serviceInsts.Select(x => x.Value))
            {
                //var value = service.CreateExport().Value;

                serviceInstances.TryAdd(command.CommandName.ToLower(), command);

                var serviceRoute = new Route();

                serviceRoute.action = async(RouteRequest request) =>
                {
                    request.action.AddEvent("Action Started");

                    //check if we should use the new command engine
                    //if (DelegateManager.GetDelegate(request.service) != null) return await
                    //await ProcessCommand(request);

                    var commandMap = CommandManager.GetCommandParamMap(command.GetType());

                    request.action.AddEvent("Paramaters Mapped");

                    // if (request.user == null && command.BypassAuthentication == false) throw new Exception($"Anonymous access it prohibited for the {command.CommandName.InsertSpaces()} service");

                    if (request.user != null && command.BypassAuthentication == false)
                    {
                        //if (!SecurityManager.IsAllowed(request.user, command.CommandName, "Command Access")) throw new Exception($"Access denied for command: '{command.CommandName.InsertSpaces()}'");
                    }

                    //if (request.user != null && command.BypassAuthentication == false && request.user.isAdmin != true)
                    //{
                    //    var userSettings = EntitySetting.EntitySettingManager.GetEntitySetting<List<NameEntity>>(typeof(IUserGroup), request.user.userGroupId.GetValueOrDefault(0), "ALLOWEDCOMMANDS");
                    //    if (!userSettings.Any(us => us.id == command.UniqueId))
                    //    {
                    //        throw new Exception($"Access denied for command: '{command.CommandName}'");
                    //    }
                    //}


                    object result = null;

                    var    userId = "2";
                    double elapsedMilliseconds = 0;

                    try
                    {
                        //lock (fileDebugLock)
                        //{
                        //    try
                        //    {
                        //        System.IO.File.AppendAllText(GlobalsManager.GetCurrentDirectory + "Temp_Service_Execution_Log.txt", $"{System.Threading.Thread.CurrentThread.ManagedThreadId},{commandMap.CommandName},{userId},{DateTime.Now.ToString()}\r\n ");
                        //    }
                        //    catch (Exception ex)
                        //    {
                        //    }
                        //}

                        //if (command.MaxSimultaneousExecutions > 0 && command.MaxSimultaneousExecutions < commandMap.CurrentlyRunning)
                        //{
                        //    //throw new Exception($"Max Simultaneous Executions Exceeded: {commandMap.CurrentlyRunning}");
                        //}

                        var startTime = DateTime.Now;

                        //commandMap.CurrentlyRunning++;

                        result = await commandMap.CallRunMethod(request.parameters, request.contentStr, request);

                        //commandMap.CurrentlyRunning--;

                        //var endTime = DateTime.Now;
                        var runTime = (DateTime.Now - startTime);
                        elapsedMilliseconds = runTime.TotalMilliseconds;

                        try
                        {
                            //commandMap.Executions += 1;
                            //commandMap.TotalExecutionTime = commandMap.TotalExecutionTime.Add(runTime);
                            //if (commandMap.SlowestExecutionTime < runTime)
                            //{
                            //    commandMap.SlowestExecutionTime = runTime;
                            //    commandMap.SlowestExecutionTimeDate = startTime;
                            //}
                        }
                        catch (Exception ex)
                        {
                            //do nothing as this was a thread lock exception
                        }

                        //lock (fileDebugLock)
                        //{
                        //    try
                        //    {
                        //        System.IO.File.AppendAllText(GlobalsManager.GetCurrentDirectory + "Temp_Service_Execution_Log.txt", $"{System.Threading.Thread.CurrentThread.ManagedThreadId},{commandMap.CommandName},{userId},{DateTime.Now.ToString()}, {elapsedMilliseconds}\r\n ");
                        //    }
                        //    catch (Exception ex)
                        //    {
                        //    }
                        //}


                        try
                        {
                            object res = result;
                            if (result is CommandResponse)
                            {
                                res = "COMMAND RESPONSE";
                            }

                            //if(!request.fullUrl.Contains("debug")) CommandLogManager.LogServiceRequest(commandMap.CommandName, request.fullUrl, userId, request.contentStr, res, false, elapsedMilliseconds);
                        }
                        catch (Exception exLog)
                        {
                            //SystemEventManager.WriteError(request, "Error writing command log: " + exLog.Message);
                            //throw;
                        }
                    }
                    catch (Exception ex)
                    {
                        //commandMap.CurrentlyRunning--;
                        if (ex.InnerException != null)
                        {
                            ex = ex.InnerException;
                        }
                        //SystemEventManager.WriteError(request, "Command Exception: " + ex.Message);
                        try
                        {
                            // CommandLogManager.LogServiceRequest(commandMap.CommandName, request.fullUrl, request.user, request.contentStr, ex.ToString(), true, elapsedMilliseconds, request.token);

                            request.action.AddEvent("Service Request Logged");
                        }
                        catch (Exception exLog)
                        {
                            // SystemEventManager.WriteError(request, "Error writing command log: " + exLog.Message);
                        }

                        return(new CommandResponse($"{{\"ex\": \"{ex.Message.Replace("\r", "").Replace("\n", "").Replace("\"", "'")}\"}}", "application/json"));
                    }

                    if (command.LogRequests)
                    {
                        var resultStr = "null";
                        if (result != null)
                        {
                            try
                            {
                                resultStr = JsonManager.Serialize(result);
                            }
                            catch (Exception ex)
                            {
                                resultStr = result.ToString();
                                throw;
                            }
                        }
                        // CommandLogManager.LogServiceRequest(commandMap.CommandName, request.fullUrl, request.user, request.contentStr, resultStr, false, elapsedMilliseconds, request.token);
                    }

                    return(result);
                };

                RegisterRoute("s", command.CommandName.ToLower(), serviceRoute);
            }
            #endregion

            #region Files

            var streamResolverRoute = new Route();
            //var streamResolverService = UnityManager.GetCommand<StreamResolver>(); //serviceInstances["streamresolver"] as IStreamResolverCommand;

            //streamResolverRoute.action = async (RouteRequest request) =>
            //{
            //    var fileName = request.service.Split('&')[0];

            //    var result = streamResolverService.Run("");

            //    if (fileName.EndsWith(".manifest"))
            //    {
            //        //result.ContentType = "text/cache-manifest";

            //        byte[] bytes = null;

            //        bytes = System.Text.Encoding.UTF8.GetBytes("\r#" + GlobalsManager.StartupTime + "\r");

            //      //  var ms = result.value as MemoryStream;

            //       // var msBytes = ms.ToArray();
            //        //byte[] newArray = new byte[msBytes.Length + bytes.Length];
            //        //Array.Copy(msBytes, newArray, msBytes.Length);
            //        //Array.Copy(bytes, 0, newArray, msBytes.Length, bytes.Length);

            //       // result.value = new MemoryStream(newArray);
            //      //  ms.Position = 0;
            //    }
            //    //else if (fileName.EndsWith(".css")) result.ContentType = "text/css";
            //    //else if (fileName.EndsWith(".js")) result.ContentType = "text/javascript";
            //    //else if (fileName.EndsWith(".png")) result.ContentType = "text/png";
            //    //else if (fileName.EndsWith(".jpg")) result.ContentType = "text/jpg";
            //    //else if (fileName.EndsWith(".gif")) result.ContentType = "text/gif";
            //    //else if (fileName.EndsWith(".html")) result.ContentType = "text/html";

            //    return result;
            //};

            RegisterRoute("f", "*", streamResolverRoute);


            #endregion
        }
        public static async Task <bool> RouteRequest(HttpResponse httpResponse, string requestPath, string requestMethod, string requestContentStr, string accepts, string user, string token, HttpRequest request = null, ActiveAction action = null)
        {
            if (accepts == null)
            {
                accepts = "*/*";
            }

            if (requestPath.StartsWith("/"))
            {
                requestPath = requestPath.Substring(1);
            }

            var path  = requestPath;
            var query = "";

            if (path.Contains("?"))
            {
                path  = requestPath.Substring(0, requestPath.IndexOf("?"));
                query = requestPath.Substring(requestPath.IndexOf("?"));
            }
            ;

            //check for any pre-defined routes
            ActionRoute route = null;

            if (routes.ContainsKey(path))
            {
                route       = routes[path];
                requestPath = route.replacement + query;
            }
            else
            {
                //default to files if no function path
                if (!requestPath.StartsWith("s/") && !requestPath.StartsWith("q/") && !requestPath.StartsWith("ui/") && !requestPath.StartsWith("f/") && !requestPath.StartsWith("c/"))
                {
                    if (requestPath.Contains("."))
                    {
                        requestPath = "f/" + requestPath;
                    }
                    else
                    {
                        requestPath = "f/index.html";
                    }
                }
            }

            var isFileRequest = requestPath.StartsWith("f/");

            var function    = requestPath.Substring(0, requestPath.IndexOf("/"));
            var serviceName = requestPath.Substring(function.Length + 1);
            var parameters  = "";

            if (serviceName.Contains("?"))
            {
                var questionIndex = serviceName.IndexOf("?");
                parameters  = serviceName.Substring(questionIndex + 1);
                serviceName = serviceName.Substring(0, questionIndex);
            }

            if (isFileRequest == false && user == null && route?.anonymous == false)
            {
                var reqPath = request.Path.ToUriComponent();
                if (reqPath.Contains("?"))
                {
                    reqPath = reqPath.Substring(0, reqPath.IndexOf("?"));
                }

                var redirectResponse = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    StatusCode = HttpStatusCode.Moved
                };

                var redirPath = "http://" + request.Host.Value + "/login?r=" + reqPath;

                httpResponse.Redirect(redirPath);
                return(true);
            }

            var routeRequest = new RouteRequest();

            routeRequest.contentStr  = requestContentStr;
            routeRequest.fullUrl     = requestPath;
            routeRequest.parameters  = parameters;
            routeRequest.hostName    = "";
            routeRequest.user        = user;
            routeRequest.function    = function;
            routeRequest.service     = serviceName;
            routeRequest.httpRequest = request;
            routeRequest.action      = action;
            routeRequest.token       = token;

            var result = await RouteManager.Process(function, serviceName, routeRequest);

            action.AddEvent("Route Processed");

            if (result == null)
            {
                result = "";
            }

            //if (result != null)
            //if (result.GetType() != typeof(RequestError))
            //{
            var resultStr = "";

            if (routeRequest.responseContentType != "")
            {
                accepts = routeRequest.responseContentType;
            }

            if (requestPath.Contains("plugins/cordova"))
            {
                accepts = "application/javascript";
            }

            var returnType = "";

            if (result is CommandResponse)
            {
                var commandResponse = ((CommandResponse)result);

                httpResponse.StatusCode = commandResponse.Status;

                if (!String.IsNullOrEmpty(request?.ContentType))
                {
                    accepts = request.ContentType;
                }

                if (request.Headers.ContainsKey("Accept"))
                {
                    var firstHeader = request.Headers["Accept"].FirstOrDefault();
                    if (firstHeader == null)
                    {
                        firstHeader = "";
                    }
                    if (firstHeader.Split(',')[0] != "*/*")
                    {
                        returnType = request.Headers["Accept"].First().Split(',')[0];
                    }
                    if (accepts != "*/*")
                    {
                        returnType = accepts;
                    }
                }

                if (commandResponse.ContentType != "")
                {
                    returnType = commandResponse.ContentType;
                }

                if (returnType == "")
                {
                    returnType = "application/json";
                }

                httpResponse.Headers.Append("Content-Type", returnType);

                foreach (var header in commandResponse.Headers)
                {
                    httpResponse.Headers.Append(header.Key, header.Value);
                }

                if (commandResponse.Bytes != null)
                {
                    var bytes = commandResponse.Bytes.ToArray();
                    await httpResponse.Body.WriteAsync(bytes, 0, bytes.Length);
                }
                else if (!String.IsNullOrWhiteSpace(commandResponse.Content))
                {
                    await httpResponse.WriteAsync(commandResponse.Content);
                }
                else if (commandResponse.value is MemoryStream)
                {
                    var bytes = ((MemoryStream)commandResponse.value).ToArray();
                    await httpResponse.Body.WriteAsync(bytes, 0, bytes.Length);
                }
                else
                {
                    await httpResponse.WriteAsync(commandResponse.value == null? "" : commandResponse.value.ToString());
                }
                return(true);
            }
            //else if (result is IEntity) resultStr = ((IEntity)result).ToJson();
            else
            {
                try
                {
                    resultStr = JsonManager.Serialize(result);
                }
                catch (Exception ex)
                {
                    var resultType = result == null ? "null" : result.GetType().ToString();
                    resultStr = $"Error with serialization of type {resultType}. {ex.Message} ";
                }
            }

            if (request.Headers.ContainsKey("Accept"))
            {
                var firstHeader = request.Headers["Accept"].FirstOrDefault();
                if (firstHeader == null)
                {
                    firstHeader = "";
                }
                if (firstHeader.Split(',')[0] != "*/*")
                {
                    returnType = request.Headers["Accept"].First().Split(',')[0];
                }
                if (accepts != "*/*")
                {
                    returnType = accepts;
                }
            }

            if (returnType == "")
            {
                returnType = "application/json";
            }


            var writeStart = DateTime.Now;

            resultStr = resultStr == null ? "" : resultStr;

            httpResponse.StatusCode = 200;
            httpResponse.Headers.Append("Content-Type", returnType);
            await httpResponse.WriteAsync(resultStr);

            //log the write time
            TotalWriteMs   += (DateTime.Now - writeStart).TotalMilliseconds;
            TotalBytesSent += resultStr.Length * 2;
            TotalRequests++;

            //
            if (TotalRequests >= 1000)
            {
                TotalWriteMs   = 0;
                TotalBytesSent = 0;
                TotalRequests  = 0;
            }

            //response.Content.Headers.ContentType = new MediaTypeHeaderValue(returnType);

            return(true);
            //}

            //return false;
        }