package main

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"

	"go.b0esche.cloud/backend/internal/audit"
	"go.b0esche.cloud/backend/internal/auth"
	"go.b0esche.cloud/backend/internal/config"
	"go.b0esche.cloud/backend/internal/database"
	httpsrv "go.b0esche.cloud/backend/internal/http"
	"go.b0esche.cloud/backend/pkg/jwt"
)

// ensureAvatarCacheDir finds a writable, preferably persistent directory for avatar cache and updates cfg
func ensureAvatarCacheDir(cfg *config.Config) {
	candidates := []string{
		cfg.AvatarCacheDir,
		"/var/lib/b0esche/avatars",
		"./data/avatars",
		filepath.Join(os.TempDir(), "b0esche_avatars"),
	}

	for _, d := range candidates {
		if d == "" {
			continue
		}
		if err := os.MkdirAll(d, 0755); err == nil {
			// Try writing a small test file to confirm write permission
			testPath := filepath.Join(d, ".write_test")
			if err := os.WriteFile(testPath, []byte("ok"), 0644); err == nil {
				os.Remove(testPath)
				if d != cfg.AvatarCacheDir {
					fmt.Printf("[WARN] Avatar cache dir %q not usable, using %q instead. Please set AVATAR_CACHE_DIR to a persistent, writable volume.\n", cfg.AvatarCacheDir, d)
				}
				cfg.AvatarCacheDir = d
				fmt.Printf("[INFO] Avatar cache directory set to %q\n", d)
				return
			}
		}
	}
	// If none usable, keep configured value and let runtime fallback handle it
	fmt.Printf("[WARN] No writable persistent avatar cache directory found; falling back to tmp. Set AVATAR_CACHE_DIR to a persistent path.\n")
}

func main() {
	cfg := config.Load()

	// Ensure avatar cache directory is usable and persistent when possible
	ensureAvatarCacheDir(cfg)

	dbConn, err := database.Connect(cfg)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Database connection error: %v\n", err)
		os.Exit(1)
	}
	db := database.New(dbConn)

	jwtManager := jwt.NewManager(cfg.JWTSecret)

	authService := auth.NewService(db)

	auditLogger := audit.NewLogger(db)

	srv := httpsrv.New(cfg, db, jwtManager, authService, auditLogger)

	fmt.Printf("Starting server on %s\n", cfg.ServerAddr)
	if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		fmt.Fprintf(os.Stderr, "Server error: %v\n", err)
		os.Exit(1)
	}
}
