package cybersecurity

import (
	"fmt"
	"net"
	"time"
)

// ScanPortTCP intenta conectarse a un puerto TCP y devuelve el estado ("open", "closed", "filtered"),
// un banner si el puerto esta abierto, y un posible error.
func ScanPortTCP(host string, port int, timeoutMs int) (status string, banner string, err error) {
	address := fmt.Sprintf("%s:%d", host, port)
	timeout := time.Duration(timeoutMs) * time.Millisecond

	conn, err := net.DialTimeout("tcp", address, timeout)
	if err != nil {
		// Distinguir entre conexion rechazada (closed) y timeout (filtered)
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			return "filtered", "", nil
		}
		return "closed", "", nil
	}
	defer conn.Close()

	// Intentar leer un banner con timeout corto
	_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
	buf := make([]byte, 1024)
	n, _ := conn.Read(buf)
	if n > 0 {
		banner = string(buf[:n])
	}

	return "open", banner, nil
}
