# Config pakcage
This package will make a global config management package for an app.
This package work wil component who's will make the real intelligence of the config.
For example, the main config file is not existing into this config, because is generated by the sum of all component config part. 

## Exmaple of implement
You can follow the initialization define into the [`cobra` package](../cobra/README.md)
Here we will define the intialization of the config package.

### Main init of config :

Make a package's file to be called by yours application command or routers
Into this file we will use some import
```go
import (
    "fmt"
    "net/http"

    liberr "github.com/nabbar/golib/errors"
    libsts "github.com/nabbar/golib/status"
    liblog "github.com/nabbar/golib/logger"
    librtr "github.com/nabbar/golib/router"
	
    cmphea "github.com/nabbar/golib/config/components/head"
    cmphtp "github.com/nabbar/golib/config/components/http"
    cmplog "github.com/nabbar/golib/config/components/log"
    cmptls "github.com/nabbar/golib/config/components/tls"

    compkg "../pkg"
)
```

Some constant to prevents error on copy/paste :
```go
const (
    ConfigKeyHead = "headers"
    ConfigKeyHttp = "servers"
    ConfigKeyLog  = "log"
    ConfigKeyTls  = "tls"
)
```

This function will init the libs and return the lib resource.
This is an example, but you can create your own component to add it into you config.
The config can have multi instance of same component type but with different config key.
As That, you can for example define a TLS config for HTTP server, a TLS config for a client, ...

```go
func SetConfig(lvl liblog.Level, handler map[string]http.Handler) {
    compkg.GetConfig().ComponentSet(ConfigKeyHead, cmphea.New())
    compkg.GetConfig().ComponentSet(ConfigKeyLog, cmplog.New(lvl, compkg.GetLogger))
    compkg.GetConfig().ComponentSet(ConfigKeyTls, cmptls.New())
    compkg.GetConfig().ComponentSet(ConfigKeyHttp, cmphtp.New(_ConfigKeyTls, _ConfigKeyLog, handler))
}

// This function will return the router header based of the component header stored into the config
func GetHeader() librtr.Headers {
    if cmp := cmphea.Load(compkg.GetConfig().ComponentGet, _ConfigKeyHead); cmp != nil {
        return cmp.GetHeaders()
    } else {
        GetLog().Fatal("component '%s' is not initialized", _ConfigKeyHead)
        return nil
    }
}

// This function will return the logger for the application. 
// If the component is not started, this function will return the root logger  
func GetLog() liblog.Logger {
    if !compkg.GetConfig().ComponentIsStarted() {
        return nil
    }

    if cmp := cmplog.Load(compkg.GetConfig().ComponentGet, _ConfigKeyLog); cmp != nil {
        return cmp.Log()
    } else {
        compkg.GetLogger().Error("component '%s' is not initialized", _ConfigKeyLog)
        return compkg.GetLogger()
    }
}
```

This function will connect the `status` package of golib with the `httpserver` package stored into the config :

```go
// This function can be call by the implementation of Status Package to expose the status of the pool web server
// This function will update the status after each reload the pool web server.
func SetRouteStatus(sts libsts.RouteStatus) {
    compkg.GetConfig().RegisterFuncReloadAfter(func() liberr.Error {
        var cmp cmphtp.ComponentHttp

		// If component has not been started, skill the function
        if !compkg.GetConfig().ComponentIsStarted() {
            return nil
        }

		// if cannot access to the Http component, generate an error
        if cmp = cmphtp.Load(compkg.GetConfig().ComponentGet, ConfigKeyHttp); cmp == nil {
            return ErrorComponentNotInitialized.ErrorParent(fmt.Errorf("component '%s'", ConfigKeyHttp))
        }

		// Get the Pool Server
        pool := cmp.GetPool()
        pool.StatusRoute(_ConfigKeyHttp, GetRouteStatusMessage, sts)
		
		// Don't forget to update the component pool
        cmp.SetPool(pool)

        return nil
    })
}

```

To generate the config example, just call this function : 
```go
    compkg.GetConfig().DefaultConfig()
```
This function will associate the config Key with the component default config into a main buffer to return it.
As that, config can be extended easily with many component and the config is automatically managed.