private static void Order()
        {
            if (context.Location == null)
            {
                Console.WriteLine("Please select a location before creating a new order.");
                return;
            }
            if (context.LoggedIn == null || !context.LoggedIn.IsUser)
            {
                Console.WriteLine("Please login as a user before creating a new order.");
                return;
            }
            ActionDict actions = new ActionDict();

            foreach (var command in new string[] { "p", "prebuilt" })
            {
                actions.Add(command, s => { SelectorGenerator(context.GetPresets, context.PresetPizza, "preset")(s); PizzaBuilder(); });
            }
            foreach (var command in new string[] { "c", "custom" })
            {
                actions.Add(command, Custom);
            }
            actions.Add("preview", Preview);
            actions.Add("confirm", Confirm);
            actions.Add("cancel", Cancel);
            context.NewOrder();
            IOrder preview;

            while (context.InOrder)
            {
                preview = context.PreviewOrder();
                string[] sep = prompt($"{preview.Pizzas.Count()} Pizzas @ {preview.Price:C}").Split(null, 2);
                sep[0] = sep[0].ToLower();
                try
                {
                    actions[sep[0]](sep.ElementAtOrDefault(1));
                }
                catch (KeyNotFoundException)
                {
                    InvalidCommand(sep[0], actions);
                }
                catch (InvalidOperationException e)
                {
                    Console.WriteLine(e.Message);
                }

                catch (PizzaBoxException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (NotImplementedException)
                {
                    Console.WriteLine($"The functionality of {sep[0]} is not available yet. Please try again in the future.");
                }
            }
        }
        private static void Sales(string modifier)
        {
            if (context.LoggedIn == null || !context.LoggedIn.IsStore)
            {
                throw new InvalidOperationException("You must be logged in as a store to view sales");
            }
            ActionDict actions = new ActionDict();

            foreach (var command in new string[] { "day", "d" })
            {
                actions.Add(command, SalesByDay);
            }
            foreach (var command in new string[] { "month", "m" })
            {
                actions.Add(command, SalesByMonth);
            }
            actions.Add("cancel", () => { });
            string [] sep;
            if (modifier == null)
            {
                sep = prompt("{[m]onth|[d]ay} (count)").Split(null, 2);
            }
            else
            {
                sep = modifier.Split(null, 2);
            }
            while (true)
            {
                sep[0] = sep[0].ToLower();
                try
                {
                    actions[sep[0]](sep.ElementAtOrDefault(1));
                    break;
                }
                catch (KeyNotFoundException)
                {
                    InvalidCommand(sep[0], actions);
                }
                catch (InvalidOperationException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (PizzaBoxException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (NotImplementedException)
                {
                    Console.WriteLine($"The functionality of {sep[0]} is not available yet. Please try again in the future.");
                }
                sep = prompt("{[m]onth|[d]ay} (count)").Split(null, 2);
            }
        }
        private static void PizzaBuilder()
        {
            if (!context.InPizza)
            {
                return;
            }
            ActionDict actions = new ActionDict();

            foreach (var command in new string[] { "topping", "add" })
            {
                actions.Add(command, SelectorGenerator(context.GetToppings, context.AddTopping, "topping"));
            }
            foreach (var command in new string[] { "s", "size" })
            {
                actions.Add(command, SelectorGenerator(context.GetSizes, context.SetSize, "size"));
            }
            foreach (var command in new string[] { "c", "crust" })
            {
                actions.Add(command, SelectorGenerator(context.GetCrusts, context.SetCrust, "crust"));
            }
            actions.Add("remove", SelectorGenerator(() => from topping in context.PreviewPizza().Toppings select topping.Name, context.RemoveTopping, "topping"));
            actions.Add("confirm", ConfirmPizza);
            actions.Add("preview", PreviewPizza);
            actions.Add("cancel", context.CancelPizza);
            IPizza preview;

            while (context.InPizza)
            {
                preview = context.PreviewPizza();
                string[] sep = prompt($"{preview.Toppings.Count()} Topping {preview.Size.Name} Pizza @ {preview.Price:C}").Split(null, 2);
                sep[0] = sep[0].ToLower();
                try
                {
                    actions[sep[0]](sep.ElementAtOrDefault(1));
                }
                catch (KeyNotFoundException)
                {
                    InvalidCommand(sep[0], actions);
                }
                catch (InvalidOperationException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (PizzaBoxException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (NotImplementedException)
                {
                    Console.WriteLine($"The functionality of {sep[0]} is not available yet. Please try again in the future.");
                }
            }
        }
 private static Action <string> SelectorGenerator(Func <IEnumerable <string> > inFunc, Action <string> outFunc, string type)
 {
     return(new Action <string>(selection => {
         IEnumerable <string> vals = inFunc();
         ActionDict actions = new ActionDict();
         foreach (string val in vals)
         {
             actions.Add(val.ToLower(), s => outFunc(val));
         }
         if (selection == null)
         {
             actions.Help();
             selection = prompt($"Select a {type} from the above list or cancel").ToLower().Trim();
         }
         do
         {
             try
             {
                 actions[selection](null);
                 break;
             }
             catch (KeyNotFoundException)
             {
                 if (selection == "cancel")
                 {
                     break;
                 }
                 else
                 {
                     InvalidCommand(selection, actions);
                 }
             }
             catch (InvalidOperationException e)
             {
                 Console.WriteLine(e.Message);
             }
             catch (PizzaBoxException e)
             {
                 Console.WriteLine(e.Message);
             }
             catch (NotImplementedException)
             {
                 Console.WriteLine($"The functionality of {selection} is not available yet. Please try again in the future.");
             }
             selection = prompt($"Select a {type} or cancel").ToLower().Trim();
         } while (true);
     }));
 }
        static void Main(string[] _args)
        {
            context = ContextDBBacked.Context;
            context.GetToppings();
            ActionDict actions = new ActionDict();

            #region required
            foreach (var command in new string[] { "login", "signin" })
            {
                actions.Add(command, Login);
            }
            foreach (var command in new string[] { "ls", "locs", "locations" })
            {
                actions.Add(command, Locations);
            }
            foreach (var command in new string[] { "loc", "location" })
            {
                actions.Add(command, SelectorGenerator(Location, context.SetStore, "store"));
            }
            foreach (var command in new string[] { "new", "order" })
            {
                actions.Add(command, Order);
            }
            actions.Add("history", History);
            foreach (var command in new string[] { "logout", "signout" })
            {
                actions.Add(command, context.Logout);
            }
            foreach (var command in new string[] { "quit", "exit", "end" })
            {
                actions.Add(command, Quit);
            }
            #endregion
            #region optional
            actions.Add("register", Register);
            actions.Add("sales", Sales);
            actions.Add("users", Users);
            actions.Add("inventory", SelectorGenerator(Inventory, s => { Console.WriteLine(context.GetInventory(s)); }, "topping"));
            #endregion
            Console.WriteLine("Welcome to Revature Pizza Portal");
            Console.WriteLine("Valid commands are listed below.");
            actions.Help();
            string input;
            while (!finished && (input = prompt(
                                     #region uglyPrompt
                                     $"{((context.LoggedIn!=null)?context.LoggedIn.Username:"******")}{((context.Location!=null)?$"@{context.Location.Name}":"")}"
                                     #endregion
                                     )) != null)
            {
                string[] sep = input.Split(null, 2);
                sep[0] = sep[0].ToLower();
                try
                {
                    actions[sep[0]](sep.ElementAtOrDefault(1));
                } catch (KeyNotFoundException)
                {
                    InvalidCommand(sep[0], actions);
                } catch (InvalidOperationException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (PizzaBoxException e)
                {
                    Console.WriteLine(e.Message);
                }
                catch (NotImplementedException)
                {
                    Console.WriteLine($"The functionality of {sep[0]} is not available yet. Please try again in the future.");
                }
            }
        }