package api

import (
	"strings"
	"testing"
)

func TestValidateModbusAddressAcceptsLANAddresses(t *testing.T) {
	for _, tc := range []struct {
		host string
		port int
	}{
		{"10.2.1.55", 502},
		{"192.168.1.40", 0}, // 0 means the standard port
		{"charger.local", 502},
		{"fd00::1", 502},
	} {
		if err := validateModbusAddress(tc.host, tc.port); err != nil {
			t.Errorf("validateModbusAddress(%q, %d) = %v, want nil", tc.host, tc.port, err)
		}
	}
}

// The server dials this address on the caller's behalf, so an address that
// resolves back to the server would point it at its own services.
func TestValidateModbusAddressRefusesLoopback(t *testing.T) {
	for _, host := range []string{"127.0.0.1", "::1", "localhost", "LocalHost", "0.0.0.0"} {
		err := validateModbusAddress(host, 502)
		if err == nil {
			t.Errorf("validateModbusAddress(%q) was accepted", host)
			continue
		}
		if !strings.Contains(err.Error(), "server itself") {
			t.Errorf("validateModbusAddress(%q) = %v, want it to say why", host, err)
		}
	}
}

func TestValidateModbusAddressRejectsMalformed(t *testing.T) {
	cases := []struct {
		name string
		host string
		port int
	}{
		{"empty host", "", 502},
		{"a URL rather than a host", "http://10.2.1.55/", 502},
		{"host with a path", "10.2.1.55/modbus", 502},
		{"port above the range", "10.2.1.55", 70000},
		{"negative port", "10.2.1.55", -1},
	}
	for _, tc := range cases {
		if err := validateModbusAddress(tc.host, tc.port); err == nil {
			t.Errorf("%s was accepted", tc.name)
		}
	}
}

func TestAnkerModbusConfigTrimsAndDefaults(t *testing.T) {
	cfg := ankerModbusConfig(ankerChargerBinding{ModbusHost: "  10.2.1.55  "})
	if cfg.Host != "10.2.1.55" {
		t.Errorf("Host = %q, want it trimmed", cfg.Host)
	}
	if got := cfg.Address(); got != "10.2.1.55:502" {
		t.Errorf("Address = %q, want the standard port filled in", got)
	}

	cfg = ankerModbusConfig(ankerChargerBinding{ModbusHost: "10.2.1.55", ModbusPort: 1502})
	if got := cfg.Address(); got != "10.2.1.55:1502" {
		t.Errorf("Address = %q, want 10.2.1.55:1502", got)
	}
}
