// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package srv

import (
	"errors"
	"net"
	"reflect"
	"strings"
	"testing"

	"github.com/coreos/etcd/pkg/testutil"
)

func TestSRVGetCluster(t *testing.T) {
	defer func() {
		lookupSRV = net.LookupSRV
		resolveTCPAddr = net.ResolveTCPAddr
	}()

	name := "dnsClusterTest"
	dns := map[string]string{
		"1.example.com.:2480": "10.0.0.1:2480",
		"2.example.com.:2480": "10.0.0.2:2480",
		"3.example.com.:2480": "10.0.0.3:2480",
		"4.example.com.:2380": "10.0.0.3:2380",
	}
	srvAll := []*net.SRV{
		{Target: "1.example.com.", Port: 2480},
		{Target: "2.example.com.", Port: 2480},
		{Target: "3.example.com.", Port: 2480},
	}

	tests := []struct {
		withSSL    []*net.SRV
		withoutSSL []*net.SRV
		urls       []string

		expected string
	}{
		{
			[]*net.SRV{},
			[]*net.SRV{},
			nil,

			"",
		},
		{
			srvAll,
			[]*net.SRV{},
			nil,

			"0=https://1.example.com:2480,1=https://2.example.com:2480,2=https://3.example.com:2480",
		},
		{
			srvAll,
			[]*net.SRV{{Target: "4.example.com.", Port: 2380}},
			nil,

			"0=https://1.example.com:2480,1=https://2.example.com:2480,2=https://3.example.com:2480,3=http://4.example.com:2380",
		},
		{
			srvAll,
			[]*net.SRV{{Target: "4.example.com.", Port: 2380}},
			[]string{"https://10.0.0.1:2480"},

			"dnsClusterTest=https://1.example.com:2480,0=https://2.example.com:2480,1=https://3.example.com:2480,2=http://4.example.com:2380",
		},
		// matching local member with resolved addr and return unresolved hostnames
		{
			srvAll,
			nil,
			[]string{"https://10.0.0.1:2480"},

			"dnsClusterTest=https://1.example.com:2480,0=https://2.example.com:2480,1=https://3.example.com:2480",
		},
		// reject if apurls are TLS but SRV is only http
		{
			nil,
			srvAll,
			[]string{"https://10.0.0.1:2480"},

			"0=http://2.example.com:2480,1=http://3.example.com:2480",
		},
	}

	resolveTCPAddr = func(network, addr string) (*net.TCPAddr, error) {
		if strings.Contains(addr, "10.0.0.") {
			// accept IP addresses when resolving apurls
			return net.ResolveTCPAddr(network, addr)
		}
		if dns[addr] == "" {
			return nil, errors.New("missing dns record")
		}
		return net.ResolveTCPAddr(network, dns[addr])
	}

	for i, tt := range tests {
		lookupSRV = func(service string, proto string, domain string) (string, []*net.SRV, error) {
			if service == "etcd-server-ssl" {
				return "", tt.withSSL, nil
			}
			if service == "etcd-server" {
				return "", tt.withoutSSL, nil
			}
			return "", nil, errors.New("Unknown service in mock")
		}
		urls := testutil.MustNewURLs(t, tt.urls)
		str, err := GetCluster("etcd-server", name, "example.com", urls)
		if err != nil {
			t.Fatalf("%d: err: %#v", i, err)
		}
		if strings.Join(str, ",") != tt.expected {
			t.Errorf("#%d: cluster = %s, want %s", i, str, tt.expected)
		}
	}
}

func TestSRVDiscover(t *testing.T) {
	defer func() { lookupSRV = net.LookupSRV }()

	tests := []struct {
		withSSL    []*net.SRV
		withoutSSL []*net.SRV
		expected   []string
	}{
		{
			[]*net.SRV{},
			[]*net.SRV{},
			[]string{},
		},
		{
			[]*net.SRV{
				{Target: "10.0.0.1", Port: 2480},
				{Target: "10.0.0.2", Port: 2480},
				{Target: "10.0.0.3", Port: 2480},
			},
			[]*net.SRV{},
			[]string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480"},
		},
		{
			[]*net.SRV{
				{Target: "10.0.0.1", Port: 2480},
				{Target: "10.0.0.2", Port: 2480},
				{Target: "10.0.0.3", Port: 2480},
			},
			[]*net.SRV{
				{Target: "10.0.0.1", Port: 7001},
			},
			[]string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480", "http://10.0.0.1:7001"},
		},
		{
			[]*net.SRV{
				{Target: "10.0.0.1", Port: 2480},
				{Target: "10.0.0.2", Port: 2480},
				{Target: "10.0.0.3", Port: 2480},
			},
			[]*net.SRV{
				{Target: "10.0.0.1", Port: 7001},
			},
			[]string{"https://10.0.0.1:2480", "https://10.0.0.2:2480", "https://10.0.0.3:2480", "http://10.0.0.1:7001"},
		},
		{
			[]*net.SRV{
				{Target: "a.example.com", Port: 2480},
				{Target: "b.example.com", Port: 2480},
				{Target: "c.example.com", Port: 2480},
			},
			[]*net.SRV{},
			[]string{"https://a.example.com:2480", "https://b.example.com:2480", "https://c.example.com:2480"},
		},
	}

	for i, tt := range tests {
		lookupSRV = func(service string, proto string, domain string) (string, []*net.SRV, error) {
			if service == "etcd-client-ssl" {
				return "", tt.withSSL, nil
			}
			if service == "etcd-client" {
				return "", tt.withoutSSL, nil
			}
			return "", nil, errors.New("Unknown service in mock")
		}

		srvs, err := GetClient("etcd-client", "example.com")
		if err != nil {
			t.Fatalf("%d: err: %#v", i, err)
		}

		if !reflect.DeepEqual(srvs.Endpoints, tt.expected) {
			t.Errorf("#%d: endpoints = %v, want %v", i, srvs.Endpoints, tt.expected)
		}

	}
}
