1 module hunt.framework.config.ConfigManager;
2 
3 import hunt.framework.application.HostEnvironment;
4 import hunt.framework.config.ApplicationConfig;
5 import hunt.framework.Init;
6 
7 import hunt.logging;
8 import hunt.util.Configuration;
9 
10 import std.exception;
11 import std.format;
12 import std.file;
13 import std.path;
14 import std.process;
15 import std.string;
16 import std.traits;
17 
18 /** 
19  * 
20  */
21 class ConfigManager {
22 
23     // TODO: Tasks pending completion -@zhangxueping at 2020-03-11T16:53:58+08:00
24     // thread-safe
25     private Object[string] _cachedConfigs;
26     private HostEnvironment _environment;
27 
28     this() {
29         _environment = new HostEnvironment();
30     }
31 
32     HostEnvironment hostEnvironment() {
33         return _environment;
34     }
35 
36     ConfigManager hostEnvironment(HostEnvironment value) {
37         _environment = value;
38         return this;
39     }
40 
41     T load(T)() {
42         static if (hasUDA!(T, ConfigurationFile)) {
43             enum string fileBaseName = getUDAs!(T, ConfigurationFile)[0].name;
44         } else {
45             enum string fileBaseName = toLower(T.stringof);
46         }
47 
48         return load!T(fileBaseName);
49     }
50 
51     T load(T)(string baseName, string section="", bool isEnvironmentEnabled = true) {
52 
53         // get from the cache
54         auto itemPtr = baseName in _cachedConfigs;
55         if (itemPtr !is null) {
56             return cast(T)*itemPtr;
57         }
58 
59         string defaultConfigFile = baseName ~ DEFAULT_CONFIG_EXT;
60         string fileName = defaultConfigFile;
61 
62         if(isEnvironmentEnabled) {
63             string env = _environment.name();
64             if (!env.empty) {
65                 fileName = baseName ~ "." ~ env ~ DEFAULT_CONFIG_EXT;
66             }            
67         }
68 
69         string _basePath = hostEnvironment.configPath();
70 
71         // Use the environment virable to set the base path
72         string configBase = environment.get(ENV_CONFIG_BASE_PATH, "");
73         if (!configBase.empty) {
74             _basePath = configBase;
75         }
76 
77         T currentConfig;
78         ConfigBuilder defaultBuilder;
79         string fullName = buildPath(APP_PATH, _basePath, fileName);
80 
81         if (exists(fullName)) {
82             version(HUNT_DEBUG) infof("Loading config from: %s", fullName);
83             defaultBuilder = new ConfigBuilder(fullName, section);
84             currentConfig = defaultBuilder.build!(T)();
85         } else {
86             version(HUNT_DEBUG) {
87                 warningf("The config file does NOT exist (Use the default instead): %s", fullName);
88             }
89             fileName = defaultConfigFile;
90             fullName = buildPath(APP_PATH, _basePath, fileName);
91             if (exists(fullName)) {
92                 version(HUNT_DEBUG) infof("Loading config from: %s", fullName);
93                 defaultBuilder = new ConfigBuilder(fullName, section);
94                 currentConfig = defaultBuilder.build!(T)();
95             } else {
96                 warningf("The config file does NOT exist (Use the default instead): %s", fullName);
97                 defaultBuilder = new ConfigBuilder();
98                 currentConfig = new T();
99             }
100         }
101 
102         _cachedConfigs[baseName] = currentConfig;
103 
104         return currentConfig;
105     }
106 }