package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"
	"time"

	"ymhut-box/server/feedback-mailer/internal/auth"
	"ymhut-box/server/feedback-mailer/internal/config"
	"ymhut-box/server/feedback-mailer/internal/db"
	"ymhut-box/server/feedback-mailer/internal/web"
)

func main() {
	baseDir := findBaseDir()
	cfg, err := config.Load(baseDir)
	if err != nil {
		log.Fatalf("load config: %v", err)
	}

	store, err := db.Open(cfg)
	if err != nil {
		log.Fatalf("open database: %v", err)
	}
	defer store.Close()

	authService := auth.NewService(cfg)
	router := web.NewRouter(cfg, store, authService)

	addr := cfg.Listen
	if addr == "" {
		addr = ":8080"
	}
	log.Printf("YMhut Box feedback service listening on %s", addr)
	server := &http.Server{Addr: addr, Handler: router}
	go func() {
		if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatalf("serve: %v", err)
		}
	}()

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()
	<-ctx.Done()

	shutdownCtx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
	defer cancel()
	if err := server.Shutdown(shutdownCtx); err != nil {
		log.Fatalf("shutdown: %v", err)
	}
	log.Println("YMhut Box feedback service stopped")
}

func findBaseDir() string {
	if value := os.Getenv("YMHUT_FEEDBACK_HOME"); value != "" {
		if abs, err := filepath.Abs(value); err == nil {
			return abs
		}
		return value
	}

	if wd, err := os.Getwd(); err == nil && looksLikeServiceRoot(wd) {
		return wd
	}

	exe, err := os.Executable()
	if err == nil {
		return filepath.Dir(exe)
	}

	wd, err := os.Getwd()
	if err == nil {
		return wd
	}

	return "."
}

func looksLikeServiceRoot(path string) bool {
	for _, name := range []string{"config.txt", "admin-web", "web"} {
		if _, err := os.Stat(filepath.Join(path, name)); err == nil {
			return true
		}
	}
	return false
}
