// Copyright 2010 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 multipart

import (
	"bytes"
	"fmt"
	"io"
	"json"
	"regexp"
	"strings"
	"testing"
)

func TestHorizontalWhitespace(t *testing.T) {
	if !onlyHorizontalWhitespace(" \t") {
		t.Error("expected pass")
	}
	if onlyHorizontalWhitespace("foo bar") {
		t.Error("expected failure")
	}
}

func TestBoundaryLine(t *testing.T) {
	boundary := "myBoundary"
	prefix := "--" + boundary
	if !isBoundaryDelimiterLine("--myBoundary\r\n", prefix) {
		t.Error("expected")
	}
	if !isBoundaryDelimiterLine("--myBoundary \r\n", prefix) {
		t.Error("expected")
	}
	if !isBoundaryDelimiterLine("--myBoundary \n", prefix) {
		t.Error("expected")
	}
	if isBoundaryDelimiterLine("--myBoundary bogus \n", prefix) {
		t.Error("expected fail")
	}
	if isBoundaryDelimiterLine("--myBoundary bogus--", prefix) {
		t.Error("expected fail")
	}
}

func escapeString(v string) string {
	bytes, _ := json.Marshal(v)
	return string(bytes)
}

func expectEq(t *testing.T, expected, actual, what string) {
	if expected == actual {
		return
	}
	t.Errorf("Unexpected value for %s; got %s (len %d) but expected: %s (len %d)",
		what, escapeString(actual), len(actual), escapeString(expected), len(expected))
}

func TestFormName(t *testing.T) {
	p := new(Part)
	p.Header = make(map[string][]string)
	tests := [...][2]string{
		{`form-data; name="foo"`, "foo"},
		{` form-data ; name=foo`, "foo"},
		{`FORM-DATA;name="foo"`, "foo"},
		{` FORM-DATA ; name="foo"`, "foo"},
		{` FORM-DATA ; name="foo"`, "foo"},
		{` FORM-DATA ; name=foo`, "foo"},
		{` FORM-DATA ; filename="foo.txt"; name=foo; baz=quux`, "foo"},
	}
	for _, test := range tests {
		p.Header.Set("Content-Disposition", test[0])
		expected := test[1]
		actual := p.FormName()
		if actual != expected {
			t.Errorf("expected \"%s\"; got: \"%s\"", expected, actual)
		}
	}
}

func TestMultipart(t *testing.T) {
	testBody := `
This is a multi-part message.  This line is ignored.
--MyBoundary
Header1: value1
HEADER2: value2
foo-bar: baz

My value
The end.
--MyBoundary
Header1: value1b
HEADER2: value2b
foo-bar: bazb

Line 1
Line 2
Line 3 ends in a newline, but just one.

--MyBoundary

never read data
--MyBoundary--
`
	testBody = regexp.MustCompile("\n").ReplaceAllString(testBody, "\r\n")
	bodyReader := strings.NewReader(testBody)

	reader := NewReader(bodyReader, "MyBoundary")
	buf := new(bytes.Buffer)

	// Part1
	part, err := reader.NextPart()
	if part == nil || err != nil {
		t.Error("Expected part1")
		return
	}
	if part.Header.Get("Header1") != "value1" {
		t.Error("Expected Header1: value")
	}
	if part.Header.Get("foo-bar") != "baz" {
		t.Error("Expected foo-bar: baz")
	}
	if part.Header.Get("Foo-Bar") != "baz" {
		t.Error("Expected Foo-Bar: baz")
	}
	buf.Reset()
	io.Copy(buf, part)
	expectEq(t, "My value\r\nThe end.",
		buf.String(), "Value of first part")

	// Part2
	part, err = reader.NextPart()
	if part == nil || err != nil {
		t.Error("Expected part2")
		return
	}
	if part.Header.Get("foo-bar") != "bazb" {
		t.Error("Expected foo-bar: bazb")
	}
	buf.Reset()
	io.Copy(buf, part)
	expectEq(t, "Line 1\r\nLine 2\r\nLine 3 ends in a newline, but just one.\r\n",
		buf.String(), "Value of second part")

	// Part3
	part, err = reader.NextPart()
	if part == nil || err != nil {
		t.Error("Expected part3 without errors")
		return
	}

	// Non-existent part4
	part, err = reader.NextPart()
	if part != nil {
		t.Error("Didn't expect a third part.")
	}
	if err != nil {
		t.Errorf("Unexpected error getting third part: %v", err)
	}
}

func TestVariousTextLineEndings(t *testing.T) {
	tests := [...]string{
		"Foo\nBar",
		"Foo\nBar\n",
		"Foo\r\nBar",
		"Foo\r\nBar\r\n",
		"Foo\rBar",
		"Foo\rBar\r",
		"\x00\x01\x02\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10",
	}

	for testNum, expectedBody := range tests {
		body := "--BOUNDARY\r\n" +
			"Content-Disposition: form-data; name=\"value\"\r\n" +
			"\r\n" +
			expectedBody +
			"\r\n--BOUNDARY--\r\n"
		bodyReader := strings.NewReader(body)

		reader := NewReader(bodyReader, "BOUNDARY")
		buf := new(bytes.Buffer)
		part, err := reader.NextPart()
		if part == nil {
			t.Errorf("Expected a body part on text %d", testNum)
			continue
		}
		if err != nil {
			t.Errorf("Unexpected error on text %d: %v", testNum, err)
			continue
		}
		written, err := io.Copy(buf, part)
		expectEq(t, expectedBody, buf.String(), fmt.Sprintf("test %d", testNum))
		if err != nil {
			t.Errorf("Error copying multipart; bytes=%v, error=%v", written, err)
		}

		part, err = reader.NextPart()
		if part != nil {
			t.Errorf("Unexpected part in test %d", testNum)
		}
		if err != nil {
			t.Errorf("Unexpected error in test %d: %v", testNum, err)
		}

	}
}
