1 module opts;
2 
3 import std.stdio  : writeln, write;
4 import std.file   : mkdirRecurse, rmdirRecurse, tempDir;
5 import std.random : Random, uniform, unpredictableSeed;
6 import std..string : leftJustifier;
7 import std.conv   : to;
8 import std.getopt : getopt, defaultGetoptPrinter;
9 import std.path   : buildPath;
10 
11 import ini : file2map, map2file;
12 
13 static import c;
14 
15 struct Opts
16 {
17 private:
18     string tmpDir;
19 
20     bool _keepTemp = false;
21 
22     bool _valid = true;
23     
24     string _configFileNew;
25 
26     string[string] _cfgMap;
27 
28     string _serverBinary = "/usr/local/bin/rocksserver";
29     string _configFile;
30 
31     string _hostDflt = "localhost";
32     string _portDflt = "5541";
33 
34     string _host;
35     string _port;
36 
37 public:
38     this(string[] args)
39     {
40         auto rnd     = Random(unpredictableSeed);
41         auto rnd_pfx = uniform(0, int.max, ).to!string;
42         tmpDir       = tempDir() ~ "/rocksserver." ~ rnd_pfx;
43 
44         _configFileNew = tmpDir ~ "/configs.ini";
45         
46         auto helpInformation = getopt(args,
47             "binary|b", 
48             "RocksServer binary file location." ~
49             "\n\t\tDefault: \"" ~ _serverBinary ~"\"",
50             &_serverBinary,
51 
52             "config|c",
53             "RocksServer config file location." ~
54             "\n\t\tBy default created automatically",
55             &_configFile,
56 
57             "tmp|t",
58             "temporary dir." ~
59             "\n\t\tDefault: \"" ~ tmpDir ~"\"\n",
60             &tmpDir,
61             
62             "host|s",
63             "DB host. Default: \"" ~ _hostDflt ~"\".\n",
64             &_host,
65             
66             "port|p",
67             "DB port. Default: \"" ~ _portDflt ~"\".\n",
68             &_port,
69             
70             "keep|k",
71             "Keep temporary files after tests finished.\n",
72             &_keepTemp
73             
74         );
75         
76 
77         if (helpInformation.helpWanted) {
78             defaultGetoptPrinter(
79                 "Run tets for drocks - RocksServer client", 
80                 helpInformation.options
81             );
82             _valid = false;
83             return;
84         }
85 
86         if(_configFile.length) {
87             _cfgMap = _configFile.file2map;
88         }
89 
90         _cfgMap["log_level"]   = "debug"; 
91         _cfgMap["error_log"]   = tmpDir ~ "/error.log"; 
92         _cfgMap["backup_path"] = tmpDir ~ "/backup"; 
93         _cfgMap["db_path"]     = tmpDir ~ "/db";
94 
95         if("extdir" !in _cfgMap) {
96             _cfgMap["extdir"] = tmpDir ~ "/plugins";
97             buildPath(tmpDir ~ "/plugins").mkdirRecurse;
98         }
99         
100         buildPath(tmpDir ~ "/backup").mkdirRecurse; 
101         buildPath(tmpDir ~ "/db")    .mkdirRecurse;
102 
103         if(_host.length) {
104             _cfgMap["server_host"] = _host;
105         } else if("server_host" in _cfgMap) {
106             _host = _cfgMap["server_host"];
107         } else {
108             _cfgMap["server_host"] = _host = _hostDflt;
109         }
110 
111         if(_port.length) {
112             _cfgMap["server_port"] = _port;
113         } else if("server_port" in _cfgMap) {
114             _port = _cfgMap["server_port"];
115         } else {
116             _cfgMap["server_port"] = _port = _portDflt;
117         }
118 
119         // Create INI configs file
120         _cfgMap.map2file(_configFileNew);
121     }
122 
123     ~this()
124     {
125         // Remove temporary dir
126         if(_valid && !_keepTemp) {
127             tmpDir.rmdirRecurse;
128         }
129     }
130 
131     bool valid() const
132     {
133         return _valid;
134     }
135     string host() const
136     {
137         return _host;
138     }
139     string port() const
140     {
141         return _port;
142     }
143 
144     string[] servOpts() const
145     {
146         return [_serverBinary, _configFileNew];
147     }
148 
149 
150     void show() const
151     {
152         writeln( c.yellow, "__________________________________________________________________", c.reset);
153         writeln( c.yellow, "RocksServer binary file location          :", c.green, _serverBinary, c.reset);
154         writeln( c.yellow, "RocksServer config file location          :", c.green, _configFile , c.reset);
155         writeln( c.yellow, "temporary dir                             :", c.green, tmpDir      , c.reset);
156         writeln( c.yellow, "DB host.                                  :", c.green, _host       , c.reset);
157         writeln( c.yellow, "DB port.                                  :", c.green, _port       , c.reset);
158 
159         writeln( c.yellow, "Keep temporary files after tests finished :", c.green, _keepTemp   , c.reset);
160 
161         writeln( c.yellow, "__________________________________________________________________", c.reset);
162 
163         // RocksServer options
164         writeln( c.blue, "RocksServer options:", c.reset);
165         foreach(key, ref val; _cfgMap) {
166             writeln( c.yellow, key.leftJustifier(20, ' '), " : ", c.green, val, c.reset);
167         }
168         writeln( c.yellow, "__________________________________________________________________", c.reset);
169     }
170 }
171