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

import (
	. "bytes";
	"rand";
	"testing";
)


const N = 10000		// make this bigger for a larger (and slower) test
var data string		// test data for write tests
var bytes []byte	// test data; same as data but as a slice.


func init() {
	bytes = make([]byte, N);
	for i := 0; i < N; i++ {
		bytes[i] = 'a' + byte(i%26)
	}
	data = string(bytes);
}

// Verify that contents of buf match the string s.
func check(t *testing.T, testname string, buf *Buffer, s string) {
	bytes := buf.Bytes();
	str := buf.String();
	if buf.Len() != len(bytes) {
		t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d\n", testname, buf.Len(), len(bytes))
	}

	if buf.Len() != len(str) {
		t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d\n", testname, buf.Len(), len(str))
	}

	if buf.Len() != len(s) {
		t.Errorf("%s: buf.Len() == %d, len(s) == %d\n", testname, buf.Len(), len(s))
	}

	if string(bytes) != s {
		t.Errorf("%s: string(buf.Bytes()) == %q, s == %q\n", testname, string(bytes), s)
	}
}


// Fill buf through n writes of string fus.
// The initial contents of buf corresponds to the string s;
// the result is the final contents of buf returned as a string.
func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {
	check(t, testname+" (fill 1)", buf, s);
	for ; n > 0; n-- {
		m, err := buf.WriteString(fus);
		if m != len(fus) {
			t.Errorf(testname+" (fill 2): m == %d, expected %d\n", m, len(fus))
		}
		if err != nil {
			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s\n", err)
		}
		s += fus;
		check(t, testname+" (fill 4)", buf, s);
	}
	return s;
}


// Fill buf through n writes of byte slice fub.
// The initial contents of buf corresponds to the string s;
// the result is the final contents of buf returned as a string.
func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
	check(t, testname+" (fill 1)", buf, s);
	for ; n > 0; n-- {
		m, err := buf.Write(fub);
		if m != len(fub) {
			t.Errorf(testname+" (fill 2): m == %d, expected %d\n", m, len(fub))
		}
		if err != nil {
			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s\n", err)
		}
		s += string(fub);
		check(t, testname+" (fill 4)", buf, s);
	}
	return s;
}


func TestNewBuffer(t *testing.T) {
	buf := NewBuffer(bytes);
	check(t, "NewBuffer", buf, data);
}


func TestNewBufferString(t *testing.T) {
	buf := NewBufferString(data);
	check(t, "NewBufferString", buf, data);
}


// Empty buf through repeated reads into fub.
// The initial contents of buf corresponds to the string s.
func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
	check(t, testname+" (empty 1)", buf, s);

	for {
		n, err := buf.Read(fub);
		if n == 0 {
			break
		}
		if err != nil {
			t.Errorf(testname+" (empty 2): err should always be nil, found err == %s\n", err)
		}
		s = s[n:len(s)];
		check(t, testname+" (empty 3)", buf, s);
	}

	check(t, testname+" (empty 4)", buf, "");
}


func TestBasicOperations(t *testing.T) {
	var buf Buffer;

	for i := 0; i < 5; i++ {
		check(t, "TestBasicOperations (1)", &buf, "");

		buf.Reset();
		check(t, "TestBasicOperations (2)", &buf, "");

		buf.Truncate(0);
		check(t, "TestBasicOperations (3)", &buf, "");

		n, err := buf.Write(Bytes(data[0:1]));
		if n != 1 {
			t.Errorf("wrote 1 byte, but n == %d\n", n)
		}
		if err != nil {
			t.Errorf("err should always be nil, but err == %s\n", err)
		}
		check(t, "TestBasicOperations (4)", &buf, "a");

		buf.WriteByte(data[1]);
		check(t, "TestBasicOperations (5)", &buf, "ab");

		n, err = buf.Write(Bytes(data[2:26]));
		if n != 24 {
			t.Errorf("wrote 25 bytes, but n == %d\n", n)
		}
		check(t, "TestBasicOperations (6)", &buf, string(data[0:26]));

		buf.Truncate(26);
		check(t, "TestBasicOperations (7)", &buf, string(data[0:26]));

		buf.Truncate(20);
		check(t, "TestBasicOperations (8)", &buf, string(data[0:20]));

		empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5));
		empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100));

		buf.WriteByte(data[1]);
		c, err := buf.ReadByte();
		if err != nil {
			t.Errorf("ReadByte unexpected eof\n")
		}
		if c != data[1] {
			t.Errorf("ReadByte wrong value c=%v\n", c)
		}
		c, err = buf.ReadByte();
		if err == nil {
			t.Errorf("ReadByte unexpected not eof\n")
		}
	}
}


func TestLargeStringWrites(t *testing.T) {
	var buf Buffer;
	for i := 3; i < 30; i += 3 {
		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, data);
		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(data)/i));
	}
	check(t, "TestLargeStringWrites (3)", &buf, "");
}


func TestLargeByteWrites(t *testing.T) {
	var buf Buffer;
	for i := 3; i < 30; i += 3 {
		s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, bytes);
		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i));
	}
	check(t, "TestLargeByteWrites (3)", &buf, "");
}


func TestLargeStringReads(t *testing.T) {
	var buf Buffer;
	for i := 3; i < 30; i += 3 {
		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, data[0:len(data)/i]);
		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)));
	}
	check(t, "TestLargeStringReads (3)", &buf, "");
}


func TestLargeByteReads(t *testing.T) {
	var buf Buffer;
	for i := 3; i < 30; i += 3 {
		s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, bytes[0:len(bytes)/i]);
		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)));
	}
	check(t, "TestLargeByteReads (3)", &buf, "");
}


func TestMixedReadsAndWrites(t *testing.T) {
	var buf Buffer;
	s := "";
	for i := 0; i < 50; i++ {
		wlen := rand.Intn(len(data));
		if i%2 == 0 {
			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, data[0:wlen])
		} else {
			s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, bytes[0:wlen])
		}

		rlen := rand.Intn(len(data));
		fub := make([]byte, rlen);
		n, _ := buf.Read(fub);
		s = s[n:len(s)];
	}
	empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()));
}


func TestNil(t *testing.T) {
	var b *Buffer;
	if b.String() != "<nil>" {
		t.Error("expcted <nil>; got %q", b.String())
	}
}
