package ping

import (
	"fmt"
	"net"
	"os/exec"
	"runtime"
	"time"
)

// PingService bietet Funktionen zum Überprüfen des Online-Status von PCs
type PingService struct{}

// NewPingService erstellt eine neue Instanz des Ping-Services
func NewPingService() *PingService {
	return &PingService{}
}

// IsOnline überprüft, ob ein PC online ist
func (ps *PingService) IsOnline(ip string) bool {
	if ip == "" {
		return false
	}

	// Verwende system-spezifischen Ping-Befehl
	switch runtime.GOOS {
	case "windows":
		return ps.pingWindows(ip)
	case "linux", "darwin":
		return ps.pingUnix(ip)
	default:
		return ps.pingGeneric(ip)
	}
}

// pingWindows führt einen Ping unter Windows aus
func (ps *PingService) pingWindows(ip string) bool {
	cmd := exec.Command("ping", "-n", "1", "-w", "1000", ip)
	err := cmd.Run()
	return err == nil
}

// pingUnix führt einen Ping unter Unix-Systemen aus
func (ps *PingService) pingUnix(ip string) bool {
	cmd := exec.Command("ping", "-c", "1", "-W", "1", ip)
	err := cmd.Run()
	return err == nil
}

// pingGeneric ist eine plattformunabhängige Alternative
func (ps *PingService) pingGeneric(ip string) bool {
	// Versuche TCP-Verbindung auf Port 80 (HTTP)
	conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:80", ip), 2*time.Second)
	if err != nil {
		// Versuche TCP-Verbindung auf Port 22 (SSH)
		conn, err = net.DialTimeout("tcp", fmt.Sprintf("%s:22", ip), 2*time.Second)
		if err != nil {
			return false
		}
	}
	defer conn.Close()
	return true
}

// CheckAllPCs überprüft den Online-Status aller PCs
func (ps *PingService) CheckAllPCs(pcs []interface{}) map[int]bool {
	results := make(map[int]bool)

	for _, pc := range pcs {
		// Type assertion für PC-Interface
		if pcMap, ok := pc.(map[string]interface{}); ok {
			if id, ok := pcMap["id"].(float64); ok {
				if ip, ok := pcMap["ip"].(string); ok {
					results[int(id)] = ps.IsOnline(ip)
				}
			}
		}
	}

	return results
}
