func LoadConfig(path string, logger log.Logger) (*Config, error) {
	fi, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	if fi.IsDir() {
		return LoadConfigDir(path, logger)
	} else {
		return LoadConfigFile(path, logger)
	}
}
LoadConfig loads the configuration at the given path, regardless if
its a file or directory.
package server
import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	log "github.com/mgutz/logxi/v1"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/hcl"
	"github.com/hashicorp/hcl/hcl/ast"
)
type Config struct {
	Listeners []*Listener `hcl:"-"`
	Backend   *Backend    `hcl:"-"`
	HABackend *Backend    `hcl:"-"`
	CacheSize    int  `hcl:"cache_size"`
	DisableCache bool `hcl:"disable_cache"`
	DisableMlock bool `hcl:"disable_mlock"`
	Telemetry *Telemetry `hcl:"telemetry"`
	MaxLeaseTTL        time.Duration `hcl:"-"`
	MaxLeaseTTLRaw     string        `hcl:"max_lease_ttl"`
	DefaultLeaseTTL    time.Duration `hcl:"-"`
	DefaultLeaseTTLRaw string        `hcl:"default_lease_ttl"`
	ClusterName string `hcl:"cluster_name"`
}
func DevConfig(ha bool) *Config {
	ret := &Config{
		DisableCache: false,
		DisableMlock: true,
		Backend: &Backend{
			Type: "inmem",
		},
		Listeners: []*Listener{
			&Listener{
				Type: "tcp",
				Config: map[string]string{
					"address":     "127.0.0.1:8200",
					"tls_disable": "1",
				},
			},
		},
		Telemetry: &Telemetry{},
		MaxLeaseTTL:     32 * 24 * time.Hour,
		DefaultLeaseTTL: 32 * 24 * time.Hour,
	}
	if ha {
		ret.Backend.Type = "inmem_ha"
	}
	return ret
}
type Listener struct {
	Type   string
	Config map[string]string
}
func (l *Listener) GoString() string {
	return fmt.Sprintf("*%#v", *l)
}
type Backend struct {
	Type              string
	RedirectAddr      string
	ClusterAddr       string
	DisableClustering bool
	Config            map[string]string
}
func (b *Backend) GoString() string {
	return fmt.Sprintf("*%#v", *b)
}
type Telemetry struct {
	StatsiteAddr string `hcl:"statsite_address"`
	StatsdAddr   string `hcl:"statsd_address"`
	DisableHostname bool `hcl:"disable_hostname"`
	CirconusAPIToken string `hcl:"circonus_api_token"`
	CirconusAPIApp string `hcl:"circonus_api_app"`
	CirconusAPIURL string `hcl:"circonus_api_url"`
	CirconusSubmissionInterval string `hcl:"circonus_submission_interval"`
	CirconusCheckSubmissionURL string `hcl:"circonus_submission_url"`
	CirconusCheckID string `hcl:"circonus_check_id"`
	CirconusCheckForceMetricActivation string `hcl:"circonus_check_force_metric_activation"`
	CirconusCheckInstanceID string `hcl:"circonus_check_instance_id"`
	CirconusCheckSearchTag string `hcl:"circonus_check_search_tag"`
	CirconusCheckTags string `mapstructure:"circonus_check_tags"`
	CirconusCheckDisplayName string `mapstructure:"circonus_check_display_name"`
	CirconusBrokerID string `hcl:"circonus_broker_id"`
	CirconusBrokerSelectTag string `hcl:"circonus_broker_select_tag"`
}
func (s *Telemetry) GoString() string {
	return fmt.Sprintf("*%#v", *s)
}
func (c *Config) Merge(c2 *Config) *Config {
	if c2 == nil {
		return c
	}
	result := new(Config)
	for _, l := range c.Listeners {
		result.Listeners = append(result.Listeners, l)
	}
	for _, l := range c2.Listeners {
		result.Listeners = append(result.Listeners, l)
	}
	result.Backend = c.Backend
	if c2.Backend != nil {
		result.Backend = c2.Backend
	}
	result.HABackend = c.HABackend
	if c2.HABackend != nil {
		result.HABackend = c2.HABackend
	}
	result.Telemetry = c.Telemetry
	if c2.Telemetry != nil {
		result.Telemetry = c2.Telemetry
	}
	result.CacheSize = c.CacheSize
	if c2.CacheSize != 0 {
		result.CacheSize = c2.CacheSize
	}
	result.DisableCache = c.DisableCache
	if c2.DisableCache {
		result.DisableCache = c2.DisableCache
	}
	result.DisableMlock = c.DisableMlock
	if c2.DisableMlock {
		result.DisableMlock = c2.DisableMlock
	}
	result.MaxLeaseTTL = c.MaxLeaseTTL
	if c2.MaxLeaseTTL > result.MaxLeaseTTL {
		result.MaxLeaseTTL = c2.MaxLeaseTTL
	}
	result.DefaultLeaseTTL = c.DefaultLeaseTTL
	if c2.DefaultLeaseTTL > result.DefaultLeaseTTL {
		result.DefaultLeaseTTL = c2.DefaultLeaseTTL
	}
	result.ClusterName = c.ClusterName
	if c2.ClusterName != "" {
		result.ClusterName = c2.ClusterName
	}
	return result
}