// Copyright 2009 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.

package net

import (
	"bytes"
	"encoding/json"
	"errors"
	"internal/testenv"
	"os/exec"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"testing"
)

var nslookupTestServers = []string{"mail.golang.com", "gmail.com"}

func toJson(v interface{}) string {
	data, _ := json.Marshal(v)
	return string(data)
}

func TestLookupMX(t *testing.T) {
	testenv.MustHaveExternalNetwork(t)

	for _, server := range nslookupTestServers {
		mx, err := LookupMX(server)
		if err != nil {
			t.Error(err)
			continue
		}
		if len(mx) == 0 {
			t.Errorf("no results")
			continue
		}
		expected, err := nslookupMX(server)
		if err != nil {
			t.Logf("skipping failed nslookup %s test: %s", server, err)
		}
		sort.Sort(byPrefAndHost(expected))
		sort.Sort(byPrefAndHost(mx))
		if !reflect.DeepEqual(expected, mx) {
			t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(mx))
		}
	}
}

func TestLookupCNAME(t *testing.T) {
	testenv.MustHaveExternalNetwork(t)

	for _, server := range nslookupTestServers {
		cname, err := LookupCNAME(server)
		if err != nil {
			t.Errorf("failed %s: %s", server, err)
			continue
		}
		if cname == "" {
			t.Errorf("no result %s", server)
		}
		expected, err := nslookupCNAME(server)
		if err != nil {
			t.Logf("skipping failed nslookup %s test: %s", server, err)
			continue
		}
		if expected != cname {
			t.Errorf("different results %s:\texp:%v\tgot:%v", server, expected, cname)
		}
	}
}

func TestLookupNS(t *testing.T) {
	testenv.MustHaveExternalNetwork(t)

	for _, server := range nslookupTestServers {
		ns, err := LookupNS(server)
		if err != nil {
			t.Errorf("failed %s: %s", server, err)
			continue
		}
		if len(ns) == 0 {
			t.Errorf("no results")
			continue
		}
		expected, err := nslookupNS(server)
		if err != nil {
			t.Logf("skipping failed nslookup %s test: %s", server, err)
			continue
		}
		sort.Sort(byHost(expected))
		sort.Sort(byHost(ns))
		if !reflect.DeepEqual(expected, ns) {
			t.Errorf("different results %s:\texp:%v\tgot:%v", toJson(server), toJson(expected), ns)
		}
	}
}

func TestLookupTXT(t *testing.T) {
	testenv.MustHaveExternalNetwork(t)

	for _, server := range nslookupTestServers {
		txt, err := LookupTXT(server)
		if err != nil {
			t.Errorf("failed %s: %s", server, err)
			continue
		}
		if len(txt) == 0 {
			t.Errorf("no results")
			continue
		}
		expected, err := nslookupTXT(server)
		if err != nil {
			t.Logf("skipping failed nslookup %s test: %s", server, err)
			continue
		}
		sort.Strings(expected)
		sort.Strings(txt)
		if !reflect.DeepEqual(expected, txt) {
			t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(txt))
		}
	}
}

type byPrefAndHost []*MX

func (s byPrefAndHost) Len() int { return len(s) }
func (s byPrefAndHost) Less(i, j int) bool {
	if s[i].Pref != s[j].Pref {
		return s[i].Pref < s[j].Pref
	}
	return s[i].Host < s[j].Host
}
func (s byPrefAndHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

type byHost []*NS

func (s byHost) Len() int           { return len(s) }
func (s byHost) Less(i, j int) bool { return s[i].Host < s[j].Host }
func (s byHost) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func nslookup(qtype, name string) (string, error) {
	var out bytes.Buffer
	var err bytes.Buffer
	cmd := exec.Command("nslookup", "-querytype="+qtype, name)
	cmd.Stdout = &out
	cmd.Stderr = &err
	if err := cmd.Run(); err != nil {
		return "", err
	}
	r := strings.Replace(out.String(), "\r\n", "\n", -1)
	// nslookup stderr output contains also debug information such as
	// "Non-authoritative answer" and it doesn't return the correct errcode
	if strings.Contains(err.String(), "can't find") {
		return r, errors.New(err.String())
	}
	return r, nil
}

func nslookupMX(name string) (mx []*MX, err error) {
	var r string
	if r, err = nslookup("mx", name); err != nil {
		return
	}
	mx = make([]*MX, 0, 10)
	// linux nslookup syntax
	// golang.org      mail exchanger = 2 alt1.aspmx.l.google.com.
	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+mail exchanger\s*=\s*([0-9]+)\s*([a-z0-9.\-]+)$`)
	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
		pref, _, _ := dtoi(ans[2], 0)
		mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)})
	}
	// windows nslookup syntax
	// gmail.com       MX preference = 30, mail exchanger = alt3.gmail-smtp-in.l.google.com
	rx = regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+MX preference\s*=\s*([0-9]+)\s*,\s*mail exchanger\s*=\s*([a-z0-9.\-]+)$`)
	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
		pref, _, _ := dtoi(ans[2], 0)
		mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)})
	}
	return
}

func nslookupNS(name string) (ns []*NS, err error) {
	var r string
	if r, err = nslookup("ns", name); err != nil {
		return
	}
	ns = make([]*NS, 0, 10)
	// golang.org      nameserver = ns1.google.com.
	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+nameserver\s*=\s*([a-z0-9.\-]+)$`)
	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
		ns = append(ns, &NS{absDomainName([]byte(ans[2]))})
	}
	return
}

func nslookupCNAME(name string) (cname string, err error) {
	var r string
	if r, err = nslookup("cname", name); err != nil {
		return
	}
	// mail.golang.com canonical name = golang.org.
	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+canonical name\s*=\s*([a-z0-9.\-]+)$`)
	// assumes the last CNAME is the correct one
	last := name
	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
		last = ans[2]
	}
	return absDomainName([]byte(last)), nil
}

func nslookupTXT(name string) (txt []string, err error) {
	var r string
	if r, err = nslookup("txt", name); err != nil {
		return
	}
	txt = make([]string, 0, 10)
	// linux
	// golang.org      text = "v=spf1 redirect=_spf.google.com"

	// windows
	// golang.org      text =
	//
	//    "v=spf1 redirect=_spf.google.com"
	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+text\s*=\s*"(.*)"$`)
	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
		txt = append(txt, ans[2])
	}
	return
}
