package system

import (
	"log"
	"time"

	"zlh-agent/internal/state"
)

/*
   autostart.go
   Handles:
     - Optional auto-start on LXC boot
     - Optional crash backoff / retry
     - Global control for enabling/disabling auto-start

   NOTE:
     - This file does NOT call StartServer automatically unless
       AutoStartEnabled == true.

     - The template can choose to enable auto-start by writing a small
       JSON flag into the payload config, or the API can set it.
*/

var AutoStartEnabled = false  // controlled by config or template
var AutoRestartOnCrash = true // can be disabled for debugging

// optional exponential backoff (3 attempts max)
var backoffDelays = []time.Duration{
	5 * time.Second,
	10 * time.Second,
	20 * time.Second,
}

/* --------------------------------------------------------------------------
   InitAutoStart — called from main.go
----------------------------------------------------------------------------*/

func InitAutoStart() {
	if !AutoStartEnabled {
		log.Println("[autostart] disabled (ok)")
		return
	}

	log.Println("[autostart] enabled: waiting for config...")

	go func() {
		// Wait until config is loaded
		for {
			cfg, err := state.LoadConfig()
			if err == nil && cfg != nil {
				log.Println("[autostart] config detected: boot-starting server")
				_ = StartServer(cfg)
				go monitorCrashes(cfg)
				return
			}
			time.Sleep(3 * time.Second)
		}
	}()
}

/* --------------------------------------------------------------------------
   monitorCrashes — restarts server if AutoRestartOnCrash=true
----------------------------------------------------------------------------*/

func monitorCrashes(cfg *state.Config) {
	if !AutoRestartOnCrash {
		log.Println("[autostart] crash monitoring disabled")
		return
	}

	attempt := 0

	for {
		time.Sleep(3 * time.Second)

		if state.GetState() != state.StateCrashed {
			continue
		}

		log.Println("[autostart] SERVER CRASH DETECTED")

		if attempt >= len(backoffDelays) {
			log.Println("[autostart] max crash retries reached, not restarting")
			return
		}

		wait := backoffDelays[attempt]
		log.Printf("[autostart] waiting %s before restart", wait)

		time.Sleep(wait)
		attempt++

		if err := StartServer(cfg); err != nil {
			log.Println("[autostart]", err)
		}
	}
}
