func LoadEnv() (C, error) {
	var c C
	if p := os.Getenv("PORT"); len(p) > 0 {
		u, err := strconv.ParseUint(p, 10, 16)
		if err != nil {
			return C{}, fmt.Errorf("failed to parse PORT: %w", err)
		}
		c.Port = uint16(u)
	}
	if r := os.Getenv("REDIS_URL"); len(r) > 0 {
		c.Redis.Insecure = os.Getenv("GOPHER_REDIS_INSECURE") == "1"
		c.Redis.SkipVerify = os.Getenv("GOPHER_REDIS_SKIPVERIFY") == "1"
		a, u, p, err := secureRedisCredentials(r, c.Redis.Insecure)
		if err != nil {
			return C{}, fmt.Errorf("failed to parse REDIS_URL: %w", err)
		}
		c.Redis.Addr = a
		c.Redis.User = u
		c.Redis.Password = p
	}
	ll := os.Getenv("GOPHER_LOG_LEVEL")
	if len(ll) == 0 {
		ll = "info"
	}
	l, err := zerolog.ParseLevel(ll)
	if err != nil {
		return C{}, fmt.Errorf("failed to parse GOPHER_LOG_LEVEL: %w", err)
	}
	c.LogLevel = l
	c.Env = strToEnv(os.Getenv("ENV"))
	c.Heroku.AppID = os.Getenv("HEROKU_APP_ID")
	c.Heroku.AppName = os.Getenv("HEROKU_APP_NAME")
	c.Heroku.DynoID = os.Getenv("HEROKU_DYNO_ID")
	c.Heroku.Commit = os.Getenv("HEROKU_SLUG_COMMIT")
	c.Slack.AppID = os.Getenv("GOPHER_SLACK_APP_ID")
	c.Slack.TeamID = os.Getenv("GOPHER_SLACK_TEAM_ID")
	c.Slack.ClientID = os.Getenv("GOPHER_SLACK_CLIENT_ID")
	c.Slack.RequestToken = os.Getenv("GOPHER_SLACK_REQUEST_TOKEN")
	c.Slack.ClientSecret = os.Getenv("GOPHER_SLACK_CLIENT_SECRET")
	c.Slack.RequestSecret = os.Getenv("GOPHER_SLACK_REQUEST_SECRET")
	c.Slack.BotAccessToken = os.Getenv("GOPHER_SLACK_BOT_ACCESS_TOKEN")
	_ = os.Unsetenv("GOPHER_SLACK_CLIENT_SECRET")     
	_ = os.Unsetenv("GOPHER_SLACK_REQUEST_SECRET")    
	_ = os.Unsetenv("GOPHER_SLACK_BOT_ACCESS_TOKEN")  
	return c, nil
}
LoadEnv loads the configuration from the appropriate environment variables.
package config
import (
	"crypto/tls"
	"fmt"
	"net"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
	"github.com/go-redis/redis"
	"github.com/rs/zerolog"
)
type Environment string
const (
	Development Environment = "development"
	Testing Environment = "testing"
	Staging Environment = "staging"
	Production Environment = "production"
)
func strToEnv(s string) Environment {
	switch strings.ToLower(s) {
	case "production":
		return Production
	case "staging":
		return Staging
	case "testing":
		return Testing
	default:
		return Development
	}
}
type R struct {
	Addr string
	User string
	Password string
	Insecure bool
	SkipVerify bool
}
type H struct {
	AppID string
	AppName string
	DynoID string
	Commit string
}
type S struct {
	AppID string
	TeamID string
	BotAccessToken string
	ClientID string
	ClientSecret string
	RequestSecret string
	RequestToken string
}
type C struct {
	LogLevel zerolog.Level
	Env Environment
	Port uint16
	Heroku H
	Redis R
	Slack S
}
func secureRedisCredentials(s string, insecure bool) (host, user, password string, err error) {
	u, err := url.Parse(s)
	if err != nil {
		return "", "", "", err
	}
	switch u.Scheme {
	case "rediss":
		pass, _ := u.User.Password()
		return u.Host, u.User.Username(), pass, nil
	case "redis":
		h, p, err := net.SplitHostPort(u.Host)
		if err != nil {
			if !strings.Contains(err.Error(), "missing port in address") {
				return "", "", "", err
			}
			h = u.Host
		}
		if p == "" {
			p = "6379"
		}
		pi, err := strconv.Atoi(p)
		if err != nil {
			return "", "", "", err
		}
		if !insecure {  
			pi++
		}
		pass, _ := u.User.Password()
		return net.JoinHostPort(h, strconv.Itoa(pi)), u.User.Username(), pass, nil
	default:
		return "", "", "", fmt.Errorf("unknown scheme: %s", u.Scheme)
	}
}