//go:build !windows

package client

import "testing"

func TestSplitHostPort(t *testing.T) {
	host, port, ok := splitHostPort("0.0.0.0:22")
	if !ok || host != "0.0.0.0" || port != "22" {
		t.Fatalf("ipv4: host=%q port=%q ok=%v", host, port, ok)
	}
	host, port, ok = splitHostPort("[::1]:443")
	if !ok || host != "::1" || port != "443" {
		t.Fatalf("ipv6: host=%q port=%q ok=%v", host, port, ok)
	}
	_, _, ok = splitHostPort("bad")
	if ok {
		t.Fatal("invalid addr should fail")
	}
}

func TestParseSSOutput(t *testing.T) {
	raw := `State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=1234,fd=3))
LISTEN 0      128             [::]:443           [::]:*    users:(("nginx",pid=5678,fd=5))
`
	r := &ListenPortsReport{}
	parseSSOutput(r, raw)
	if len(r.Ports) != 2 {
		t.Fatalf("expected 2 ports, got %d: %+v", len(r.Ports), r.Ports)
	}
	if r.Ports[0].Port != 22 || r.Ports[0].Process != "sshd" || r.Ports[0].PID != 1234 {
		t.Fatalf("port 22: %+v", r.Ports[0])
	}
	if r.Ports[1].Port != 443 || r.Ports[1].Process != "nginx" {
		t.Fatalf("port 443: %+v", r.Ports[1])
	}
}

func TestParseSSOutputDedupesPorts(t *testing.T) {
	raw := `LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1,fd=1))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=2,fd=2))
`
	r := &ListenPortsReport{}
	parseSSOutput(r, raw)
	if len(r.Ports) != 1 {
		t.Fatalf("duplicate port should dedupe, got %d", len(r.Ports))
	}
}

func TestParseNetstatOutput(t *testing.T) {
	raw := `Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1234/sshd
tcp6       0      0 :::8080                 :::*                    LISTEN      5678/java
udp        0      0 0.0.0.0:123             0.0.0.0:*                           999/chronyd
`
	r := &ListenPortsReport{}
	parseNetstatOutput(r, raw)
	if len(r.Ports) != 2 {
		t.Fatalf("expected 2 tcp listeners, got %d: %+v", len(r.Ports), r.Ports)
	}
	if r.Ports[0].Port != 22 || r.Ports[0].PID != 1234 || r.Ports[0].Process != "sshd" {
		t.Fatalf("first: %+v", r.Ports[0])
	}
	if r.Ports[1].Port != 8080 {
		t.Fatalf("second: %+v", r.Ports[1])
	}
}
