package config
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/PacktPublishing/Hands-On-Dependency-Injection-in-Go/ch12/acme/internal/logging"
)
// DefaultEnvVar is the default environment variable the points to the config file
const DefaultEnvVar = "ACME_CONFIG"
// Config defines the JSON format for the config file
type Config struct {
// DSN is the data source name (format: https://github.com/go-sql-driver/mysql/#dsn-data-source-name)
DSN string
// Address is the IP address and port to bind this rest to
Address string
// BasePrice is the price of registration
BasePrice float64
// ExchangeRateBaseURL is the server and protocol part of the URL from which to load the exchange rate
ExchangeRateBaseURL string
// ExchangeRateAPIKey is the API for the exchange rate API
ExchangeRateAPIKey string
// environmental dependencies
logger logging.Logger
}
// Logger returns a reference to the singleton logger
func (c *Config) Logger() logging.Logger {
if c.logger == nil {
c.logger = &logging.LoggerStdOut{}
}
return c.logger
}
// RegistrationBasePrice returns the base price for registrations
func (c *Config) RegistrationBasePrice() float64 {
return c.BasePrice
}
// DataDSN returns the DSN
func (c *Config) DataDSN() string {
return c.DSN
}
// ExchangeBaseURL returns the Base URL from which we can load exchange rates
func (c *Config) ExchangeBaseURL() string {
return c.ExchangeRateBaseURL
}
// ExchangeAPIKey returns the DSN
func (c *Config) ExchangeAPIKey() string {
return c.ExchangeRateAPIKey
}
// BindAddress returns the host and port this service should bind to
func (c *Config) BindAddress() string {
return c.Address
}
// Load returns the config loaded from environment
func Load() (*Config, error) {
filename, found := os.LookupEnv(DefaultEnvVar)
if !found {
err := fmt.Errorf("failed to locate file specified by %s", DefaultEnvVar)
fmt.Fprintf(os.Stderr, err.Error())
return nil, err
}
cfg, err := load(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load config with err %s", err)
return nil, err
}
return cfg, nil
}
func load(filename string) (*Config, error) {
out := &Config{}
bytes, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read config file. err: %s", err)
return nil, err
}
err = json.Unmarshal(bytes, out)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to parse config file. err : %s", err)
return nil, err
}
return out, nil
}