package resolver_test

import (
	"ekdns/resolver"
	"strings"
	"testing"
)

// ---------------------------------------------------------------------------
// ParseServerFlag
// ---------------------------------------------------------------------------

func TestParseServerFlag(t *testing.T) {
	tests := []struct {
		name          string
		input         string
		wantMode      string
		wantAddr      string
		wantErrSubstr string
	}{
		{
			name:     "empty string gives default",
			input:    "",
			wantMode: "default",
		},
		{
			name:     "local lower-case",
			input:    "local",
			wantMode: "local",
		},
		{
			name:     "LOCAL upper-case",
			input:    "LOCAL",
			wantMode: "local",
		},
		{
			name:     "gateway lower-case",
			input:    "gateway",
			wantMode: "gateway",
		},
		{
			name:     "GATEWAY upper-case",
			input:    "GATEWAY",
			wantMode: "gateway",
		},
		{
			name:     "explicit bare IP",
			input:    "10.0.0.53",
			wantMode: "explicit",
			wantAddr: "10.0.0.53",
		},
		{
			name:     "explicit IP with port",
			input:    "10.0.0.53:5353",
			wantMode: "explicit",
			wantAddr: "10.0.0.53:5353",
		},
		{
			name:          "port zero is invalid",
			input:         "10.0.0.53:0",
			wantErrSubstr: "port must be between 1 and 65535",
		},
		{
			name:          "port too large",
			input:         "10.0.0.53:99999",
			wantErrSubstr: "port",
		},
		{
			name:          "not an IP",
			input:         "notanip",
			wantErrSubstr: "invalid",
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got, err := resolver.ParseServerFlag(tc.input)
			if tc.wantErrSubstr != "" {
				if err == nil {
					t.Fatalf("expected error containing %q, got nil", tc.wantErrSubstr)
				}
				if !strings.Contains(err.Error(), tc.wantErrSubstr) {
					t.Errorf("error %q does not contain %q", err.Error(), tc.wantErrSubstr)
				}
				return
			}
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if got.Mode != tc.wantMode {
				t.Errorf("Mode: got %q, want %q", got.Mode, tc.wantMode)
			}
			if got.ExplicitAddr != tc.wantAddr {
				t.Errorf("ExplicitAddr: got %q, want %q", got.ExplicitAddr, tc.wantAddr)
			}
		})
	}
}

// ---------------------------------------------------------------------------
// ExtractLabelLevels
// ---------------------------------------------------------------------------

func TestExtractLabelLevels(t *testing.T) {
	tests := []struct {
		name     string
		input    string
		expected []string
	}{
		{
			name:  "multi-level hostname",
			input: "host1.sub.domain.example.com",
			expected: []string{
				"host1.sub.domain.example.com",
				"sub.domain.example.com",
				"domain.example.com",
				"example.com",
			},
		},
		{
			name:  "three-label hostname",
			input: "www.example.com",
			expected: []string{
				"www.example.com",
				"example.com",
			},
		},
		{
			name:     "two-label hostname",
			input:    "example.com",
			expected: []string{"example.com"},
		},
		{
			name:     "single label returns nil",
			input:    "localhost",
			expected: nil,
		},
		{
			name:     "trailing dot stripped",
			input:    "example.com.",
			expected: []string{"example.com"},
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got := resolver.ExtractLabelLevels(tc.input)
			if len(got) != len(tc.expected) {
				t.Fatalf("got %v (len %d), want %v (len %d)", got, len(got), tc.expected, len(tc.expected))
			}
			for i := range got {
				if got[i] != tc.expected[i] {
					t.Errorf("[%d]: got %q, want %q", i, got[i], tc.expected[i])
				}
			}
		})
	}
}
