func WithKey(key string) *AppConf {
	appConf := Manager()
	if appConf != nil && appConf.Confs != nil {
		c, ok := appConf.Confs[key]
		if c != nil && ok {
			return c
		}
	}
	return nil
}
WithKey returns the key app config
package conf
import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
	"github.com/axfor/bast/ids"
	"github.com/axfor/bast/logs"
	sessionConf "github.com/axfor/bast/session/conf"
)
var (
	flagConf, flagAppKey string
	confObj              *AppConfMgr
	confHandle           ConfingHandle
	confFinishHandle     FinishHandle
)
type ConfingHandle func(appConf *AppConf) error
type FinishHandle func(appConf *AppConf) error
type AppConfMgr struct {
	frist    *AppConf
	rawConfs []AppConf
	Confs    map[string]*AppConf
}
type AppConf struct {
	Key          string            `json:"key"`
	Name         string            `json:"name"`
	Addr         string            `json:"addr"`
	CertFile     string            `json:"certFile"`  
	KeyFile      string            `json:"keyFile"`   
	FileDir      string            `json:"fileDir"`
	Debug        bool              `json:"debug"`
	BaseURL      string            `json:"baseUrl"`
	IDNode       uint8             `json:"idNode"`     
	Lang         string            `json:"lang"`       
	Trans        string            `json:"trans"`      
	SameSiteText string            `json:"sameSite"`   
	Wrap         *bool             `json:"wrap"`       
	Session      *sessionConf.Conf `json:"session"`    
	Log          *logs.Conf        `json:"log"`        
	CORS         *CORSConf         `json:"cors"`       
	Conf         interface{}       `json:"conf"`       
	Extend       string            `json:"extend"`     
	Page         *PaginationConf   `json:"page"`       
	Registry     *RegistryConf     `json:"registry"`   
	Discovery    *DiscoveryConf    `json:"discovery"`  
	Shutdown     int64             `json:"shutdown"`   
	SameSite     http.SameSite     `json:"-"`
	initTag      bool
}
type CORSConf struct {
	AllowOrigin      string `json:"allowOrigin"`
	AllowMethods     string `json:"allowMethods"`
	AllowHeaders     string `json:"allowHeaders"`
	AllowCredentials string `json:"allowCredentials"`
	MaxAge           string `json:"maxAge"`
}
type PaginationConf struct {
	Page    string `json:"page"`
	Total   string `json:"total"`
	PageRow string `json:"pageRow"`
}
type RegistryConf struct {
	Enable      bool   `json:"enable"`     
	BaseURL     string `json:"baseUrl"`    
	Prefix      string `json:"prefix"`     
	Endpoints   string `json:"endpoints"`  
	DialTimeout int64  `json:"timeout"`    
	TTL         int64  `json:"ttl"`
}
type DiscoveryConf struct {
	Enable      bool   `json:"enable"`     
	Prefix      string `json:"prefix"`     
	Endpoints   string `json:"endpoints"`  
	DialTimeout int64  `json:"timeout"`    
}
func Init() {
	if confObj == nil {
		data, err := ioutil.ReadFile(Path())
		if err != nil {
			logs.Errors("read conf error", err)
			return
		}
		s := strings.TrimSpace(string(data))
		isAdd := (s[0] != '[')
		if isAdd && s[0] != '{' {
			s = "{" + s + "}"
		}
		if isAdd {
			s = "[" + s + "]"
			data = []byte(s)
		}
		appConf := []AppConf{}
		err = json.Unmarshal(data, &appConf)
		if err != nil {
			logs.Errors("conf manager init error", err)
			return
		}
		if confObj != nil {
			return
		}
		confObj = &AppConfMgr{}
		confObj.rawConfs = appConf
		confObj.Confs = make(map[string]*AppConf)
		lg := len(appConf)
		if lg > 0 {
			for i := 0; i < lg; i++ {
				c := &appConf[i]
				appConfWithInit(c)
				if c.Key == flagAppKey && confObj.frist == nil {
					confObj.frist = c
				}
				confObj.Confs[c.Key] = c
			}
			if confObj.frist == nil {
				confObj.frist = &appConf[0]
			}
			if confObj.frist != nil {
				ids.SetIDNode(confObj.frist.IDNode)
			}
			callbackHandle()
		}
	}
}
func Manager() *AppConfMgr {
	if confObj == nil {
		Init()
	}
	return confObj
}
func appConfWithInit(c *AppConf) {
	if c.initTag {
		return
	}
	c.initTag = true
	if c.Lang == "" {
		c.Lang = "en"
	}
	c.SameSite = sameSite(c.SameSiteText)
	if c.Session == nil {
		c.Session = sessionConf.NewDefault()
	} else {
		if c.Session.LifeTime <= 0 {
			c.Session.LifeTime = 20
		}
		if c.Session.Name == "" {
			c.Session.Name = "_sid"
		}
		if c.Session.Engine == "" {
			c.Session.Engine = "memory"
		}
		c.Session.LifeTime *= 60
	}
	c.Session.SameSite = c.SameSite
	if c.FileDir != "" {
		if c.FileDir[len(c.FileDir)-1] != '/' {
			c.FileDir += "/"
		}
	}
	if c.Shutdown > 0 {
		c.Shutdown *= int64(time.Microsecond)
	}
}
func callbackHandle() {
	if confObj == nil {
		return
	}
	lg := len(confObj.rawConfs)
	if lg == 0 {
		return
	}
	if confHandle != nil {
		for i := 0; i < lg; i++ {
			c := &confObj.rawConfs[i]
			err := confHandle(c)
			if err != nil {
				logs.Errors("callback conf handle error", err)
			}
		}
	}
	if confFinishHandle != nil {
		confFinishHandle(confObj.frist)
	}
}
func OK() bool {
	return Manager() != nil
}
func Lang() string {
	c := Conf()
	if c != nil {
		return c.Lang
	}
	return ""
}
func Trans() string {
	c := Conf()
	if c != nil {
		return c.Trans
	}
	return ""
}
func Confs() []AppConf {
	appConf := Manager()
	if appConf != nil && appConf.Confs != nil {
		return appConf.rawConfs
	}
	return nil
}
func Conf() *AppConf {
	appConf := Manager()
	if appConf != nil && appConf.Confs != nil {
		if flagAppKey == "" {
			return appConf.frist
		}
		c, ok := appConf.Confs[flagAppKey]
		if c != nil && ok {
			return c
		}
	}
	return nil
}