package main

import (
	"bytes"
	"fmt"
	"github.com/knadh/koanf/providers/confmap"
	"github.com/knadh/koanf/v2"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"log/slog"
	"os"
	"strings"
)

func run() error {
	v := viper.New()
	v.SetDefault("port", 8080)
	v.SetConfigType("json")
	if err := v.ReadConfig(strings.NewReader(`{"port":9000}`)); err != nil {
		return err
	}
	if err := os.Setenv("ENGINEERING_V2_PORT", "9001"); err != nil {
		return err
	}
	if err := v.BindEnv("port", "ENGINEERING_V2_PORT"); err != nil {
		return err
	}
	fmt.Println("viper env=", v.GetInt("port"))
	v.Set("port", 9002)
	fmt.Println("viper explicit=", v.GetInt("port"))
	k := koanf.New(".")
	if err := k.Load(confmap.Provider(map[string]interface{}{"port": 9000}, "."), nil); err != nil {
		return err
	}
	if err := k.Load(confmap.Provider(map[string]interface{}{"port": 9001}, "."), nil); err != nil {
		return err
	}
	fmt.Println("koanf later=", k.Int("port"))
	var out bytes.Buffer
	enc := zap.NewProductionEncoderConfig()
	enc.TimeKey = ""
	z := zap.New(zapcore.NewCore(zapcore.NewJSONEncoder(enc), zapcore.AddSync(&out), zap.InfoLevel))
	z.Info("ready", zap.Int("port", 9001))
	if err := z.Sync(); err != nil {
		return err
	}
	fmt.Print("zap ", out.String())
	out.Reset()
	s := slog.New(slog.NewJSONHandler(&out, &slog.HandlerOptions{ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr {
		if a.Key == slog.TimeKey {
			return slog.Attr{}
		}
		return a
	}}))
	s.Info("ready", slog.Int("port", 9001))
	fmt.Print("slog ", out.String())
	return nil
}
func main() {
	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
