package process

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"time"
)

const (
	rustAppID = "258550" // Rust Dedicated Server App ID
)

// SteamCMD handles SteamCMD operations for game server updates
type SteamCMD struct {
	path string
}

// NewSteamCMD creates a new SteamCMD instance
func NewSteamCMD(path string) *SteamCMD {
	return &SteamCMD{
		path: path,
	}
}

// UpdateRustServer updates the Rust Dedicated Server via SteamCMD
func (sc *SteamCMD) UpdateRustServer(validate bool) error {
	log.Printf("Starting SteamCMD update for Rust Server (validate=%v)", validate)

	// Check if SteamCMD exists
	if _, err := os.Stat(sc.path); os.IsNotExist(err) {
		return fmt.Errorf("steamcmd not found at: %s", sc.path)
	}

	startTime := time.Now()

	// Build SteamCMD command
	// +login anonymous +force_install_dir /path/to/rust +app_update 258550 validate +quit
	args := []string{
		"+login", "anonymous",
		"+force_install_dir", getServerInstallDir(),
		"+app_update", rustAppID,
	}

	if validate {
		args = append(args, "validate")
	}

	args = append(args, "+quit")

	log.Printf("Executing: %s %v", sc.path, args)

	// Create command
	cmd := exec.Command(sc.path, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// Run SteamCMD (this will block until update completes)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("steamcmd update failed: %w", err)
	}

	duration := time.Since(startTime)
	log.Printf("SteamCMD update completed in %v", duration)

	return nil
}

// UpdateRustServerWithPath updates the Rust server to a specific install directory
func (sc *SteamCMD) UpdateRustServerWithPath(installPath string, validate bool) error {
	log.Printf("Starting SteamCMD update for Rust Server at %s (validate=%v)", installPath, validate)

	// Check if SteamCMD exists
	if _, err := os.Stat(sc.path); os.IsNotExist(err) {
		return fmt.Errorf("steamcmd not found at: %s", sc.path)
	}

	startTime := time.Now()

	// Build SteamCMD command
	args := []string{
		"+login", "anonymous",
		"+force_install_dir", installPath,
		"+app_update", rustAppID,
	}

	if validate {
		args = append(args, "validate")
	}

	args = append(args, "+quit")

	log.Printf("Executing: %s %v", sc.path, args)

	// Create command
	cmd := exec.Command(sc.path, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// Run SteamCMD
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("steamcmd update failed: %w", err)
	}

	duration := time.Since(startTime)
	log.Printf("SteamCMD update completed in %v", duration)

	return nil
}

// CheckSteamCMDInstalled verifies SteamCMD is installed and executable
func (sc *SteamCMD) CheckSteamCMDInstalled() error {
	if _, err := os.Stat(sc.path); os.IsNotExist(err) {
		return fmt.Errorf("steamcmd not found at: %s", sc.path)
	}

	// Try to execute with --help or similar to verify it's executable
	cmd := exec.Command(sc.path, "+quit")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("steamcmd is not executable or working: %w", err)
	}

	return nil
}

// getServerInstallDir returns the default server installation directory
// This should ideally come from configuration, but we provide a fallback
func getServerInstallDir() string {
	// Try to determine from GAME_SERVER_PATH environment variable
	serverPath := os.Getenv("GAME_SERVER_PATH")
	if serverPath != "" {
		return getDirectory(serverPath)
	}

	// Default fallback paths by OS
	return "/home/rustserver/server"
}
