// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris

package net

import (
	"errors"
	"os"
	"reflect"
	"strings"
	"testing"
	"time"
)

var dnsReadConfigTests = []struct {
	name string
	want *dnsConfig
}{
	{
		name: "testdata/resolv.conf",
		want: &dnsConfig{
			servers:    []string{"8.8.8.8:53", "[2001:4860:4860::8888]:53", "[fe80::1%lo0]:53"},
			search:     []string{"localdomain."},
			ndots:      5,
			timeout:    10 * time.Second,
			attempts:   3,
			rotate:     true,
			unknownOpt: true, // the "options attempts 3" line
		},
	},
	{
		name: "testdata/domain-resolv.conf",
		want: &dnsConfig{
			servers:  []string{"8.8.8.8:53"},
			search:   []string{"localdomain."},
			ndots:    1,
			timeout:  5 * time.Second,
			attempts: 2,
		},
	},
	{
		name: "testdata/search-resolv.conf",
		want: &dnsConfig{
			servers:  []string{"8.8.8.8:53"},
			search:   []string{"test.", "invalid."},
			ndots:    1,
			timeout:  5 * time.Second,
			attempts: 2,
		},
	},
	{
		name: "testdata/empty-resolv.conf",
		want: &dnsConfig{
			servers:  defaultNS,
			ndots:    1,
			timeout:  5 * time.Second,
			attempts: 2,
			search:   []string{"domain.local."},
		},
	},
	{
		name: "testdata/invalid-ndots-resolv.conf",
		want: &dnsConfig{
			servers:  defaultNS,
			ndots:    0,
			timeout:  5 * time.Second,
			attempts: 2,
			search:   []string{"domain.local."},
		},
	},
	{
		name: "testdata/large-ndots-resolv.conf",
		want: &dnsConfig{
			servers:  defaultNS,
			ndots:    15,
			timeout:  5 * time.Second,
			attempts: 2,
			search:   []string{"domain.local."},
		},
	},
	{
		name: "testdata/negative-ndots-resolv.conf",
		want: &dnsConfig{
			servers:  defaultNS,
			ndots:    0,
			timeout:  5 * time.Second,
			attempts: 2,
			search:   []string{"domain.local."},
		},
	},
	{
		name: "testdata/openbsd-resolv.conf",
		want: &dnsConfig{
			ndots:    1,
			timeout:  5 * time.Second,
			attempts: 2,
			lookup:   []string{"file", "bind"},
			servers:  []string{"169.254.169.254:53", "10.240.0.1:53"},
			search:   []string{"c.symbolic-datum-552.internal."},
		},
	},
}

func TestDNSReadConfig(t *testing.T) {
	origGetHostname := getHostname
	defer func() { getHostname = origGetHostname }()
	getHostname = func() (string, error) { return "host.domain.local", nil }

	for _, tt := range dnsReadConfigTests {
		conf := dnsReadConfig(tt.name)
		if conf.err != nil {
			t.Fatal(conf.err)
		}
		conf.mtime = time.Time{}
		if !reflect.DeepEqual(conf, tt.want) {
			t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
		}
	}
}

func TestDNSReadMissingFile(t *testing.T) {
	origGetHostname := getHostname
	defer func() { getHostname = origGetHostname }()
	getHostname = func() (string, error) { return "host.domain.local", nil }

	conf := dnsReadConfig("a-nonexistent-file")
	if !os.IsNotExist(conf.err) {
		t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, os.ErrNotExist)
	}
	conf.err = nil
	want := &dnsConfig{
		servers:  defaultNS,
		ndots:    1,
		timeout:  5 * time.Second,
		attempts: 2,
		search:   []string{"domain.local."},
	}
	if !reflect.DeepEqual(conf, want) {
		t.Errorf("missing resolv.conf:\ngot: %+v\nwant: %+v", conf, want)
	}
}

var dnsDefaultSearchTests = []struct {
	name string
	err  error
	want []string
}{
	{
		name: "host.long.domain.local",
		want: []string{"long.domain.local."},
	},
	{
		name: "host.local",
		want: []string{"local."},
	},
	{
		name: "host",
		want: nil,
	},
	{
		name: "host.domain.local",
		err:  errors.New("errored"),
		want: nil,
	},
	{
		// ensures we don't return []string{""}
		// which causes duplicate lookups
		name: "foo.",
		want: nil,
	},
}

func TestDNSDefaultSearch(t *testing.T) {
	origGetHostname := getHostname
	defer func() { getHostname = origGetHostname }()

	for _, tt := range dnsDefaultSearchTests {
		getHostname = func() (string, error) { return tt.name, tt.err }
		got := dnsDefaultSearch()
		if !reflect.DeepEqual(got, tt.want) {
			t.Errorf("dnsDefaultSearch with hostname %q and error %+v = %q, wanted %q", tt.name, tt.err, got, tt.want)
		}
	}
}

func TestDNSNameLength(t *testing.T) {
	origGetHostname := getHostname
	defer func() { getHostname = origGetHostname }()
	getHostname = func() (string, error) { return "host.domain.local", nil }

	var char63 = ""
	for i := 0; i < 63; i++ {
		char63 += "a"
	}
	longDomain := strings.Repeat(char63+".", 5) + "example"

	for _, tt := range dnsReadConfigTests {
		conf := dnsReadConfig(tt.name)
		if conf.err != nil {
			t.Fatal(conf.err)
		}

		var shortestSuffix int
		for _, suffix := range tt.want.search {
			if shortestSuffix == 0 || len(suffix) < shortestSuffix {
				shortestSuffix = len(suffix)
			}
		}

		// Test a name that will be maximally long when prefixing the shortest
		// suffix (accounting for the intervening dot).
		longName := longDomain[len(longDomain)-254+1+shortestSuffix:]
		if longName[0] == '.' || longName[1] == '.' {
			longName = "aa." + longName[3:]
		}
		for _, fqdn := range conf.nameList(longName) {
			if len(fqdn) > 254 {
				t.Errorf("got %d; want less than or equal to 254", len(fqdn))
			}
		}

		// Now test a name that's too long for suffixing.
		unsuffixable := "a." + longName[1:]
		unsuffixableResults := conf.nameList(unsuffixable)
		if len(unsuffixableResults) != 1 {
			t.Errorf("suffixed names %v; want []", unsuffixableResults[1:])
		}

		// Now test a name that's too long for DNS.
		tooLong := "a." + longDomain
		tooLongResults := conf.nameList(tooLong)
		if tooLongResults != nil {
			t.Errorf("suffixed names %v; want nil", tooLongResults)
		}
	}
}
