package main

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

	agentfiles "zlh-agent/internal/files"
	agenthttp "zlh-agent/internal/http"
	"zlh-agent/internal/system"
	"zlh-agent/internal/update"
	"zlh-agent/internal/util"
	"zlh-agent/internal/version"
)

func main() {
	log.Printf("[agent] starting ZeroLagHub Agent %s", version.AgentVersion)

	// ------------------------------------------------------------
	// Optional: enable log file (safe if path doesn't exist yet)
	// ------------------------------------------------------------
	_ = os.MkdirAll("/opt/zlh-agent/logs", 0755)
	if err := util.InitLogFile("/opt/zlh-agent/logs/agent.log"); err != nil {
		log.Printf("[agent] warning: log file init failed: %v", err)
	} else {
		log.Printf("[agent] file logging enabled")
	}
	if err := util.InitLifecycleLog("/opt/zlh-agent/logs/lifecycle.log"); err != nil {
		log.Printf("[agent] warning: lifecycle log init failed: %v", err)
	} else {
		log.Printf("[agent] lifecycle logging enabled")
	}
	defer util.CloseLog()

	// ------------------------------------------------------------
	// HTTP listen address
	// ------------------------------------------------------------
	addr := ":18888"
	if v := os.Getenv("ZLH_AGENT_LISTEN"); v != "" {
		addr = v
	} else if v := os.Getenv("ZLH_AGENT_PORT"); v != "" {
		addr = ":" + v
	}

	mux := agenthttp.NewMux()

	// ------------------------------------------------------------
	// Enable autostart subsystem
	// (does nothing unless AutoStartEnabled=true)
	// ------------------------------------------------------------
	system.InitAutoStart()
	agentfiles.StartShadowCleanup()
	update.StartPeriodic(version.AgentVersion)

	server := &http.Server{
		Addr:         addr,
		Handler:      mux,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 30 * time.Second,
		IdleTimeout:  60 * time.Second,
	}

	// ------------------------------------------------------------
	// Graceful shutdown handling
	// ------------------------------------------------------------
	go func() {
		log.Printf("[agent] listening on %s", addr)
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("[agent] http server error: %v", err)
		}
	}()

	// Catch SIGINT / SIGTERM
	stop := make(chan os.Signal, 1)
	signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

	<-stop
	log.Println("[agent] shutdown signal received")

	// Allow up to 10 seconds for graceful shutdown
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Printf("[agent] http shutdown error: %v", err)
	} else {
		log.Println("[agent] http server stopped gracefully")
	}

	log.Println("[agent] exiting")
}
