package main

import (
	"fmt"
	"os"
	"strings"
)

// Config menyimpan konfigurasi aplikasi yang dibaca dari environment variable.
type Config struct {
	Port        string
	LogLevel    string
	DatabaseURL string
	APIToken    string
}

// envOr membaca environment variable; bila kosong, kembalikan nilai default.
func envOr(key, fallback string) string {
	if v := strings.TrimSpace(os.Getenv(key)); v != "" {
		return v
	}
	return fallback
}

// Load membangun Config dari environment variable dengan default aman
// dan validasi fail-fast untuk nilai wajib.
func Load() (Config, error) {
	cfg := Config{
		Port:     envOr("APP_PORT", "8080"),
		LogLevel: envOr("APP_LOG_LEVEL", "info"),
	}

	url := strings.TrimSpace(os.Getenv("APP_DATABASE_URL"))
	if url == "" {
		return cfg, fmt.Errorf("variabel APP_DATABASE_URL wajib diisi")
	}
	cfg.DatabaseURL = url

	cfg.APIToken = strings.TrimSpace(os.Getenv("APP_API_TOKEN"))
	if len(cfg.APIToken) < 20 {
		return cfg, fmt.Errorf("APP_API_TOKEN terlalu pendek: minimal 20 karakter")
	}
	return cfg, nil
}

// redact menyamarkan nilai sensitif sebelum dicetak ke layar atau log.
func redact(s string) string {
	if len(s) <= 8 {
		return "***"
	}
	return s[:8] + "***"
}

func main() {
	// Skenario 1: environment kosong → Load gagal cepat saat startup.
	fmt.Println("== Skenario 1: environment kosong ==")
	_, err := Load()
	if err != nil {
		fmt.Println("Load gagal:", err)
	}

	// Skenario 2: environment lengkap → Load berhasil.
	// Di produksi, nilai-nilai ini diisi oleh environment, bukan oleh kode.
	os.Setenv("APP_DATABASE_URL", "postgres://app:YOUR_DATABASE_PASSWORD@db.internal:5432/toko")
	os.Setenv("APP_API_TOKEN", "YOUR_API_TOKEN_1234567890abcdef")
	os.Setenv("APP_PORT", "3000")

	fmt.Println()
	fmt.Println("== Skenario 2: environment lengkap ==")
	cfg, err := Load()
	if err != nil {
		fmt.Println("Load gagal:", err)
		return
	}
	fmt.Println("Port        :", cfg.Port)
	fmt.Println("LogLevel    :", cfg.LogLevel)
	fmt.Println("DatabaseURL :", redact(cfg.DatabaseURL))
	fmt.Println("APIToken    :", redact(cfg.APIToken))
}
