package config

import (
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/joho/godotenv"
)

type Env struct {
	AppURL string
}

// LoadEnv reads .env, looking beyond the working directory.
//
// godotenv.Load() only ever looks in the process working directory, and that is
// where this bites on a server: a systemd unit, a hosting panel or a service
// wrapper commonly starts the binary from / or from its own directory, so the
// .env sitting next to the deployed binary is never read and every os.Getenv
// comes back empty. The candidates below cover that, and APP_ENV_FILE covers a
// deployment that keeps its configuration somewhere else entirely.
//
// A missing .env is only fatal when the process environment does not already
// carry the configuration: a container or a systemd unit that sets real
// environment variables needs no file at all.
func LoadEnv() {

	candidates := []string{}

	if custom := strings.TrimSpace(os.Getenv("APP_ENV_FILE")); custom != "" {
		candidates = append(candidates, custom)
	}

	candidates = append(candidates, ".env")

	if executable, err := os.Executable(); err == nil {

		candidates = append(
			candidates,
			filepath.Join(filepath.Dir(executable), ".env"),
		)
	}

	for _, candidate := range candidates {

		if err := godotenv.Load(candidate); err != nil {
			continue
		}

		absolute, err := filepath.Abs(candidate)

		if err != nil {
			absolute = candidate
		}

		log.Printf("configuration loaded from %s", absolute)

		return
	}

	// Nothing loaded. That is fine when the real environment is populated.
	if os.Getenv("DB_HOST") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_OTP_TEMPLATE_ID") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_AUTH_KEY") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_API_URL") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_SENDER_ID") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_HEADER_ID") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_PE_ID") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_OTP_EXPIRY_MINUTES") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	if os.Getenv("MSG91_OTP_LENGTH") != "" {

		log.Printf(
			"no .env file found (looked in: %s) - using the process environment",
			strings.Join(candidates, ", "),
		)

		return
	}

	log.Fatalf(
		"Error loading .env file, looked in: %s",
		strings.Join(candidates, ", "),
	)
}
