1 module hunt.framework.command.ServeCommand;
2 
3 import hunt.framework.Init;
4 
5 import hunt.console;
6 import hunt.logging;
7 
8 import core.stdc.stdlib : exit;
9 
10 import std.conv;
11 import std.format;
12 import std.range;
13 import std.string;
14 
15 /**
16  * 
17  */
18 class ServeCommand : Command {
19     enum string HostNameOption = "hostname";
20     enum string PortOption = "port";
21     enum string BindOption = "bind";
22     enum string ConfigPathOption = "config-path";
23     // enum string ConfigFileOption = "config-file";
24     enum string EnvironmentOption = "env"; // development, production, staging
25 
26     private CommandInputHandler _inputHandler;
27 
28 
29     this() {
30         super("serve");
31     }
32 
33     void onInput(CommandInputHandler handler) {
34         _inputHandler = handler;
35     }
36 
37     override protected void configure() {
38         // https://symfony.com/doc/current/components/console/console_arguments.html
39         // https://symfony.com/doc/current/console/input.html
40         setDescription("Begins serving the app over HTTP.");
41 
42         addOption(HostNameOption, "H", InputOption.VALUE_OPTIONAL,
43             "Set the hostname the server will run on. (Using the setting in config file by default)"); 
44             // DEFAULT_HOST
45             // (Using the setting in config file by default)
46 
47         addOption(PortOption, "p", InputOption.VALUE_OPTIONAL,
48             "Set the port the server will run on. (Using the setting in config file by default)"); 
49             // (Using the setting in config file.)
50 
51         addOption(BindOption, "b", InputOption.VALUE_OPTIONAL,
52             "Convenience for setting hostname and port together."); 
53             // (Using the setting in config file.)
54 
55         addOption(EnvironmentOption, "e", InputOption.VALUE_OPTIONAL,
56             "Set the runtime environment."); 
57             // DEFAULT_RUNTIME_ENVIRONMENT
58 
59         addOption(ConfigPathOption, "c", InputOption.VALUE_OPTIONAL,
60             "Set the location for config files",
61             DEFAULT_CONFIG_LACATION);
62     }
63 
64     override protected int execute(Input input, Output output) {
65         string hostname = input.getOption(HostNameOption);
66         string port = input.getOption(PortOption);
67         string bind = input.getOption(BindOption);
68         string configPath = input.getOption(ConfigPathOption);
69         // string configFile = input.getOption(ConfigFileOption);
70         string envionment = input.getOption(EnvironmentOption);
71 
72         if (!bind.empty && bind != "0.0.0.0:8080") {
73             // 0.0.0.0:8080, 0.0.0.0, parse hostname and port
74             string[] parts = bind.split(":");
75             if(parts.length<2) {
76                 output.writeln("Wrong format for the bind option.");
77                 exit(1);
78             }
79 
80             hostname = parts[0];
81             port = parts[1];
82         }
83 
84         if(port.empty()) port = "0";
85 
86         if(_inputHandler !is null) {
87             ServeSignature signature = ServeSignature(hostname, port.to!ushort, 
88                 configPath, envionment); // configFile, 
89                 
90             _inputHandler(signature);
91         }
92 
93         return 0;
94     }
95 
96     override protected void interact(Input input, Output output) {
97         // if (input.getArgument("name") is null) {
98         //     string name = (cast(QuestionHelper)(getHelper("question"))).ask(input,
99         //             output, new Question("What is your name?"));
100         //     input.setArgument("name", name);
101         // }
102     }
103 }
104 
105 /**
106  * 
107  */
108 struct ServeSignature {
109     string host = DEFAULT_HOST;
110     ushort port = DEFAULT_PORT;
111     string configPath = DEFAULT_CONFIG_LACATION;
112     // string configFile = DEFAULT_CONFIG_FILE;
113     string environment; // = DEFAULT_RUNTIME_ENVIRONMENT;
114 }
115 
116 alias CommandInputHandler = void delegate(ServeSignature signature);