// 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 xml

import (
	"bytes"
	"io"
	"os"
	"reflect"
	"testing"
)

const testInput = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<body xmlns:foo="ns1" xmlns="ns2" xmlns:tag="ns3" ` +
	"\r\n\t" + `  >
  <hello lang="en">World &lt;&gt;&apos;&quot; &#x767d;&#40300;翔</hello>
  <goodbye />
  <outer foo:attr="value" xmlns:tag="ns4">
    <inner/>
  </outer>
  <tag:name>
    <![CDATA[Some text here.]]>
  </tag:name>
</body><!-- missing final newline -->`

var rawTokens = []Token{
	CharData([]byte("\n")),
	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
	CharData([]byte("\n")),
	Directive([]byte(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
	),
	CharData([]byte("\n")),
	StartElement{Name{"", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
	CharData([]byte("\n  ")),
	StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
	CharData([]byte("World <>'\" 白鵬翔")),
	EndElement{Name{"", "hello"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"", "goodbye"}, nil},
	EndElement{Name{"", "goodbye"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"", "outer"}, []Attr{{Name{"foo", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
	CharData([]byte("\n    ")),
	StartElement{Name{"", "inner"}, nil},
	EndElement{Name{"", "inner"}},
	CharData([]byte("\n  ")),
	EndElement{Name{"", "outer"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"tag", "name"}, nil},
	CharData([]byte("\n    ")),
	CharData([]byte("Some text here.")),
	CharData([]byte("\n  ")),
	EndElement{Name{"tag", "name"}},
	CharData([]byte("\n")),
	EndElement{Name{"", "body"}},
	Comment([]byte(" missing final newline ")),
}

var cookedTokens = []Token{
	CharData([]byte("\n")),
	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
	CharData([]byte("\n")),
	Directive([]byte(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
	),
	CharData([]byte("\n")),
	StartElement{Name{"ns2", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
	CharData([]byte("\n  ")),
	StartElement{Name{"ns2", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
	CharData([]byte("World <>'\" 白鵬翔")),
	EndElement{Name{"ns2", "hello"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"ns2", "goodbye"}, nil},
	EndElement{Name{"ns2", "goodbye"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"ns2", "outer"}, []Attr{{Name{"ns1", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
	CharData([]byte("\n    ")),
	StartElement{Name{"ns2", "inner"}, nil},
	EndElement{Name{"ns2", "inner"}},
	CharData([]byte("\n  ")),
	EndElement{Name{"ns2", "outer"}},
	CharData([]byte("\n  ")),
	StartElement{Name{"ns3", "name"}, nil},
	CharData([]byte("\n    ")),
	CharData([]byte("Some text here.")),
	CharData([]byte("\n  ")),
	EndElement{Name{"ns3", "name"}},
	CharData([]byte("\n")),
	EndElement{Name{"ns2", "body"}},
	Comment([]byte(" missing final newline ")),
}

var xmlInput = []string{
	// unexpected EOF cases
	"<",
	"<t",
	"<t ",
	"<t/",
	"<!",
	"<!-",
	"<!--",
	"<!--c-",
	"<!--c--",
	"<!d",
	"<t></",
	"<t></t",
	"<?",
	"<?p",
	"<t a",
	"<t a=",
	"<t a='",
	"<t a=''",
	"<t/><![",
	"<t/><![C",
	"<t/><![CDATA[d",
	"<t/><![CDATA[d]",
	"<t/><![CDATA[d]]",

	// other Syntax errors
	"<>",
	"<t/a",
	"<0 />",
	"<?0 >",
	//	"<!0 >",	// let the Token() caller handle
	"</0>",
	"<t 0=''>",
	"<t a='&'>",
	"<t a='<'>",
	"<t>&nbspc;</t>",
	"<t a>",
	"<t a=>",
	"<t a=v>",
	//	"<![CDATA[d]]>",	// let the Token() caller handle
	"<t></e>",
	"<t></>",
	"<t></t!",
	"<t>cdata]]></t>",
}

type stringReader struct {
	s   string
	off int
}

func (r *stringReader) Read(b []byte) (n int, err os.Error) {
	if r.off >= len(r.s) {
		return 0, os.EOF
	}
	for r.off < len(r.s) && n < len(b) {
		b[n] = r.s[r.off]
		n++
		r.off++
	}
	return
}

func (r *stringReader) ReadByte() (b byte, err os.Error) {
	if r.off >= len(r.s) {
		return 0, os.EOF
	}
	b = r.s[r.off]
	r.off++
	return
}

func StringReader(s string) io.Reader { return &stringReader{s, 0} }

func TestRawToken(t *testing.T) {
	p := NewParser(StringReader(testInput))

	for i, want := range rawTokens {
		have, err := p.RawToken()
		if err != nil {
			t.Fatalf("token %d: unexpected error: %s", i, err)
		}
		if !reflect.DeepEqual(have, want) {
			t.Errorf("token %d = %#v want %#v", i, have, want)
		}
	}
}

func TestToken(t *testing.T) {
	p := NewParser(StringReader(testInput))

	for i, want := range cookedTokens {
		have, err := p.Token()
		if err != nil {
			t.Fatalf("token %d: unexpected error: %s", i, err)
		}
		if !reflect.DeepEqual(have, want) {
			t.Errorf("token %d = %#v want %#v", i, have, want)
		}
	}
}

func TestSyntax(t *testing.T) {
	for i := range xmlInput {
		p := NewParser(StringReader(xmlInput[i]))
		var err os.Error
		for _, err = p.Token(); err == nil; _, err = p.Token() {
		}
		if _, ok := err.(*SyntaxError); !ok {
			t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i])
		}
	}
}

type allScalars struct {
	True1   bool
	True2   bool
	False1  bool
	False2  bool
	Int     int
	Int8    int8
	Int16   int16
	Int32   int32
	Int64   int64
	Uint    int
	Uint8   uint8
	Uint16  uint16
	Uint32  uint32
	Uint64  uint64
	Uintptr uintptr
	Float   float
	Float32 float32
	Float64 float64
	String  string
}

var all = allScalars{
	True1:   true,
	True2:   true,
	False1:  false,
	False2:  false,
	Int:     1,
	Int8:    -2,
	Int16:   3,
	Int32:   -4,
	Int64:   5,
	Uint:    6,
	Uint8:   7,
	Uint16:  8,
	Uint32:  9,
	Uint64:  10,
	Uintptr: 11,
	Float:   12.0,
	Float32: 13.0,
	Float64: 14.0,
	String:  "15",
}

const testScalarsInput = `<allscalars>
	<true1>true</true1>
	<true2>1</true2>
	<false1>false</false1>
	<false2>0</false2>
	<int>1</int>
	<int8>-2</int8>
	<int16>3</int16>
	<int32>-4</int32>
	<int64>5</int64>
	<uint>6</uint>
	<uint8>7</uint8>
	<uint16>8</uint16>
	<uint32>9</uint32>
	<uint64>10</uint64>
	<uintptr>11</uintptr>
	<float>12.0</float>
	<float32>13.0</float32>
	<float64>14.0</float64>
	<string>15</string>
</allscalars>`

func TestAllScalars(t *testing.T) {
	var a allScalars
	buf := bytes.NewBufferString(testScalarsInput)
	err := Unmarshal(buf, &a)

	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(a, all) {
		t.Errorf("expected %+v got %+v", all, a)
	}
}

type item struct {
	Field_a string
}

func TestIssue569(t *testing.T) {
	data := `<item><field_a>abcd</field_a></item>`
	var i item
	buf := bytes.NewBufferString(data)
	err := Unmarshal(buf, &i)

	if err != nil || i.Field_a != "abcd" {
		t.Fatal("Expecting abcd")
	}
}

func TestUnquotedAttrs(t *testing.T) {
	data := "<tag attr=azAZ09:-_\t>"
	p := NewParser(StringReader(data))
	p.Strict = false
	token, err := p.Token()
	if _, ok := err.(*SyntaxError); ok {
		t.Errorf("Unexpected error: %v", err)
	}
	if token.(StartElement).Name.Local != "tag" {
		t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)
	}
	attr := token.(StartElement).Attr[0]
	if attr.Value != "azAZ09:-_" {
		t.Errorf("Unexpected attribute value: %v", attr.Value)
	}
	if attr.Name.Local != "attr" {
		t.Errorf("Unexpected attribute name: %v", attr.Name.Local)
	}
}

func TestCopyTokenCharData(t *testing.T) {
	data := []byte("same data")
	var tok1 Token = CharData(data)
	tok2 := CopyToken(tok1)
	if !reflect.DeepEqual(tok1, tok2) {
		t.Error("CopyToken(CharData) != CharData")
	}
	data[1] = 'o'
	if reflect.DeepEqual(tok1, tok2) {
		t.Error("CopyToken(CharData) uses same buffer.")
	}
}

func TestCopyTokenStartElement(t *testing.T) {
	elt := StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}
	var tok1 Token = elt
	tok2 := CopyToken(tok1)
	if !reflect.DeepEqual(tok1, tok2) {
		t.Error("CopyToken(StartElement) != StartElement")
	}
	elt.Attr[0] = Attr{Name{"", "lang"}, "de"}
	if reflect.DeepEqual(tok1, tok2) {
		t.Error("CopyToken(CharData) uses same buffer.")
	}
}

func TestSyntaxErrorLineNum(t *testing.T) {
	testInput := "<P>Foo<P>\n\n<P>Bar</>\n"
	p := NewParser(StringReader(testInput))
	var err os.Error
	for _, err = p.Token(); err == nil; _, err = p.Token() {
	}
	synerr, ok := err.(*SyntaxError)
	if !ok {
		t.Error("Expected SyntaxError.")
	}
	if synerr.Line != 3 {
		t.Error("SyntaxError didn't have correct line number.")
	}
}

func TestTrailingRawToken(t *testing.T) {
	input := `<FOO></FOO>  `
	p := NewParser(StringReader(input))
	var err os.Error
	for _, err = p.RawToken(); err == nil; _, err = p.RawToken() {
	}
	if err != os.EOF {
		t.Fatalf("p.RawToken() = _, %v, want _, os.EOF", err)
	}
}

func TestTrailingToken(t *testing.T) {
	input := `<FOO></FOO>  `
	p := NewParser(StringReader(input))
	var err os.Error
	for _, err = p.Token(); err == nil; _, err = p.Token() {
	}
	if err != os.EOF {
		t.Fatalf("p.Token() = _, %v, want _, os.EOF", err)
	}
}

func TestEntityInsideCDATA(t *testing.T) {
	input := `<test><![CDATA[ &val=foo ]]></test>`
	p := NewParser(StringReader(input))
	var err os.Error
	for _, err = p.Token(); err == nil; _, err = p.Token() {
	}
	if err != os.EOF {
		t.Fatalf("p.Token() = _, %v, want _, os.EOF", err)
	}
}


// The last three tests (respectively one for characters in attribute
// names and two for character entities) pass not because of code
// changed for issue 1259, but instead pass with the given messages
// from other parts of xml.Parser.  I provide these to note the
// current behavior of situations where one might think that character
// range checking would detect the error, but it does not in fact.

var characterTests = []struct {
	in  string
	err string
}{
	{"\x12<doc/>", "illegal character code U+0012"},
	{"<?xml version=\"1.0\"?>\x0b<doc/>", "illegal character code U+000B"},
	{"\xef\xbf\xbe<doc/>", "illegal character code U+FFFE"},
	{"<?xml version=\"1.0\"?><doc>\r\n<hiya/>\x07<toots/></doc>", "illegal character code U+0007"},
	{"<?xml version=\"1.0\"?><doc \x12='value'>what's up</doc>", "expected attribute name in element"},
	{"<doc>&\x01;</doc>", "invalid character entity &;"},
	{"<doc>&\xef\xbf\xbe;</doc>", "invalid character entity &;"},
}


func TestDisallowedCharacters(t *testing.T) {

	for i, tt := range characterTests {
		p := NewParser(StringReader(tt.in))
		var err os.Error

		for err == nil {
			_, err = p.Token()
		}
		synerr, ok := err.(*SyntaxError)
		if !ok {
			t.Fatalf("input %d p.Token() = _, %v, want _, *SyntaxError", i, err)
		}
		if synerr.Msg != tt.err {
			t.Fatalf("input %d synerr.Msg wrong: want '%s', got '%s'", i, tt.err, synerr.Msg)
		}
	}
}
