package main

import (
	"os"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	// Quick start - Development logger (human readable)
	logger, _ := zap.NewDevelopment()
	defer logger.Sync() // Flush buffered logs

	logger.Info("Development logger started",
		zap.String("mode", "development"),
		zap.Int("port", 8080),
	)

	// Production logger (JSON format, optimized)
	prodLogger, _ := zap.NewProduction()
	defer prodLogger.Sync()

	prodLogger.Info("Production logger started",
		zap.String("mode", "production"),
		zap.Duration("startup_time", 2*time.Second),
	)

	// Sugared logger - slightly slower but more convenient
	sugar := logger.Sugar()
	sugar.Infow("Sugared logging",
		"key", "value",
		"count", 42,
	)
	sugar.Infof("Printf-style: running on port %d", 8080)

	// Structured logging with typed fields (fastest)
	logger.Info("User logged in",
		zap.String("user_id", "usr_123"),
		zap.String("email", "alice@example.com"),
		zap.String("ip", "192.168.1.1"),
		zap.Time("login_time", time.Now()),
	)

	// Log levels
	logger.Debug("Debug message")
	logger.Info("Info message")
	logger.Warn("Warning message")
	logger.Error("Error message")
	// logger.Fatal("Fatal message") // would call os.Exit(1)
	// logger.Panic("Panic message") // would panic

	// Error with stack trace
	logger.Error("Database connection failed",
		zap.Error(os.ErrNotExist),
		zap.String("host", "db.example.com"),
		zap.Int("retries", 3),
	)

	// Child logger with preset fields
	requestLogger := logger.With(
		zap.String("request_id", "req_abc123"),
		zap.String("user_agent", "Mozilla/5.0"),
	)
	requestLogger.Info("Processing request")
	requestLogger.Info("Request completed")

	// Custom configuration
	config := zap.Config{
		Level:       zap.NewAtomicLevelAt(zap.InfoLevel),
		Development: false,
		Encoding:    "json", // or "console"
		EncoderConfig: zapcore.EncoderConfig{
			TimeKey:        "timestamp",
			LevelKey:       "level",
			NameKey:        "logger",
			CallerKey:      "caller",
			MessageKey:     "message",
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder,
			EncodeTime:     zapcore.ISO8601TimeEncoder,
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		},
		OutputPaths:      []string{"stdout"},
		ErrorOutputPaths: []string{"stderr"},
	}
	customLogger, _ := config.Build()
	defer customLogger.Sync()
	customLogger.Info("Custom configured logger")

	// Named loggers for different components
	dbLogger := logger.Named("database")
	apiLogger := logger.Named("api")
	dbLogger.Info("Database component log")
	apiLogger.Info("API component log")

	// Sampling (for high-volume logs)
	sampledLogger := zap.New(
		zapcore.NewSamplerWithOptions(
			logger.Core(),
			time.Second,     // interval
			100,             // first N logs per interval
			10,              // thereafter sample every Nth
		),
	)
	for i := 0; i < 200; i++ {
		sampledLogger.Info("High volume log", zap.Int("iteration", i))
	}
}
