// Copyright 2011 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 http

import (
	"bytes"
	"internal/race"
	"reflect"
	"runtime"
	"strings"
	"testing"
	"time"
)

var headerWriteTests = []struct {
	h        Header
	exclude  map[string]bool
	expected string
}{
	{Header{}, nil, ""},
	{
		Header{
			"Content-Type":   {"text/html; charset=UTF-8"},
			"Content-Length": {"0"},
		},
		nil,
		"Content-Length: 0\r\nContent-Type: text/html; charset=UTF-8\r\n",
	},
	{
		Header{
			"Content-Length": {"0", "1", "2"},
		},
		nil,
		"Content-Length: 0\r\nContent-Length: 1\r\nContent-Length: 2\r\n",
	},
	{
		Header{
			"Expires":          {"-1"},
			"Content-Length":   {"0"},
			"Content-Encoding": {"gzip"},
		},
		map[string]bool{"Content-Length": true},
		"Content-Encoding: gzip\r\nExpires: -1\r\n",
	},
	{
		Header{
			"Expires":          {"-1"},
			"Content-Length":   {"0", "1", "2"},
			"Content-Encoding": {"gzip"},
		},
		map[string]bool{"Content-Length": true},
		"Content-Encoding: gzip\r\nExpires: -1\r\n",
	},
	{
		Header{
			"Expires":          {"-1"},
			"Content-Length":   {"0"},
			"Content-Encoding": {"gzip"},
		},
		map[string]bool{"Content-Length": true, "Expires": true, "Content-Encoding": true},
		"",
	},
	{
		Header{
			"Nil":          nil,
			"Empty":        {},
			"Blank":        {""},
			"Double-Blank": {"", ""},
		},
		nil,
		"Blank: \r\nDouble-Blank: \r\nDouble-Blank: \r\n",
	},
	// Tests header sorting when over the insertion sort threshold side:
	{
		Header{
			"k1": {"1a", "1b"},
			"k2": {"2a", "2b"},
			"k3": {"3a", "3b"},
			"k4": {"4a", "4b"},
			"k5": {"5a", "5b"},
			"k6": {"6a", "6b"},
			"k7": {"7a", "7b"},
			"k8": {"8a", "8b"},
			"k9": {"9a", "9b"},
		},
		map[string]bool{"k5": true},
		"k1: 1a\r\nk1: 1b\r\nk2: 2a\r\nk2: 2b\r\nk3: 3a\r\nk3: 3b\r\n" +
			"k4: 4a\r\nk4: 4b\r\nk6: 6a\r\nk6: 6b\r\n" +
			"k7: 7a\r\nk7: 7b\r\nk8: 8a\r\nk8: 8b\r\nk9: 9a\r\nk9: 9b\r\n",
	},
	// Tests invalid characters in headers.
	{
		Header{
			"Content-Type":             {"text/html; charset=UTF-8"},
			"NewlineInValue":           {"1\r\nBar: 2"},
			"NewlineInKey\r\n":         {"1"},
			"Colon:InKey":              {"1"},
			"Evil: 1\r\nSmuggledValue": {"1"},
		},
		nil,
		"Content-Type: text/html; charset=UTF-8\r\n" +
			"NewlineInValue: 1  Bar: 2\r\n",
	},
}

func TestHeaderWrite(t *testing.T) {
	var buf strings.Builder
	for i, test := range headerWriteTests {
		test.h.WriteSubset(&buf, test.exclude)
		if buf.String() != test.expected {
			t.Errorf("#%d:\n got: %q\nwant: %q", i, buf.String(), test.expected)
		}
		buf.Reset()
	}
}

var parseTimeTests = []struct {
	h   Header
	err bool
}{
	{Header{"Date": {""}}, true},
	{Header{"Date": {"invalid"}}, true},
	{Header{"Date": {"1994-11-06T08:49:37Z00:00"}}, true},
	{Header{"Date": {"Sun, 06 Nov 1994 08:49:37 GMT"}}, false},
	{Header{"Date": {"Sunday, 06-Nov-94 08:49:37 GMT"}}, false},
	{Header{"Date": {"Sun Nov  6 08:49:37 1994"}}, false},
}

func TestParseTime(t *testing.T) {
	expect := time.Date(1994, 11, 6, 8, 49, 37, 0, time.UTC)
	for i, test := range parseTimeTests {
		d, err := ParseTime(test.h.Get("Date"))
		if err != nil {
			if !test.err {
				t.Errorf("#%d:\n got err: %v", i, err)
			}
			continue
		}
		if test.err {
			t.Errorf("#%d:\n  should err", i)
			continue
		}
		if !expect.Equal(d) {
			t.Errorf("#%d:\n got: %v\nwant: %v", i, d, expect)
		}
	}
}

type hasTokenTest struct {
	header string
	token  string
	want   bool
}

var hasTokenTests = []hasTokenTest{
	{"", "", false},
	{"", "foo", false},
	{"foo", "foo", true},
	{"foo ", "foo", true},
	{" foo", "foo", true},
	{" foo ", "foo", true},
	{"foo,bar", "foo", true},
	{"bar,foo", "foo", true},
	{"bar, foo", "foo", true},
	{"bar,foo, baz", "foo", true},
	{"bar, foo,baz", "foo", true},
	{"bar,foo, baz", "foo", true},
	{"bar, foo, baz", "foo", true},
	{"FOO", "foo", true},
	{"FOO ", "foo", true},
	{" FOO", "foo", true},
	{" FOO ", "foo", true},
	{"FOO,BAR", "foo", true},
	{"BAR,FOO", "foo", true},
	{"BAR, FOO", "foo", true},
	{"BAR,FOO, baz", "foo", true},
	{"BAR, FOO,BAZ", "foo", true},
	{"BAR,FOO, BAZ", "foo", true},
	{"BAR, FOO, BAZ", "foo", true},
	{"foobar", "foo", false},
	{"barfoo ", "foo", false},
}

func TestHasToken(t *testing.T) {
	for _, tt := range hasTokenTests {
		if hasToken(tt.header, tt.token) != tt.want {
			t.Errorf("hasToken(%q, %q) = %v; want %v", tt.header, tt.token, !tt.want, tt.want)
		}
	}
}

func TestNilHeaderClone(t *testing.T) {
	t1 := Header(nil)
	t2 := t1.Clone()
	if t2 != nil {
		t.Errorf("cloned header does not match original: got: %+v; want: %+v", t2, nil)
	}
}

var testHeader = Header{
	"Content-Length": {"123"},
	"Content-Type":   {"text/plain"},
	"Date":           {"some date at some time Z"},
	"Server":         {DefaultUserAgent},
}

var buf bytes.Buffer

func BenchmarkHeaderWriteSubset(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		buf.Reset()
		testHeader.WriteSubset(&buf, nil)
	}
}

func TestHeaderWriteSubsetAllocs(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping alloc test in short mode")
	}
	if race.Enabled {
		t.Skip("skipping test under race detector")
	}
	if runtime.GOMAXPROCS(0) > 1 {
		t.Skip("skipping; GOMAXPROCS>1")
	}
	n := testing.AllocsPerRun(100, func() {
		buf.Reset()
		testHeader.WriteSubset(&buf, nil)
	})
	if n > 0 {
		t.Errorf("allocs = %g; want 0", n)
	}
}

// Issue 34878: test that every call to
// cloneOrMakeHeader never returns a nil Header.
func TestCloneOrMakeHeader(t *testing.T) {
	tests := []struct {
		name     string
		in, want Header
	}{
		{"nil", nil, Header{}},
		{"empty", Header{}, Header{}},
		{
			name: "non-empty",
			in:   Header{"foo": {"bar"}},
			want: Header{"foo": {"bar"}},
		},
		{
			name: "nil value",
			in:   Header{"foo": nil},
			want: Header{"foo": nil},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := cloneOrMakeHeader(tt.in)
			if got == nil {
				t.Fatal("unexpected nil Header")
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Fatalf("Got:  %#v\nWant: %#v", got, tt.want)
			}
			got.Add("A", "B")
			got.Get("A")
		})
	}
}
