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

import (
	"bytes"
	"io"
	"io/ioutil"
	"runtime"
	"strconv"
	"strings"
	"testing"
)

type lzwTest struct {
	desc       string
	raw        string
	compressed string
	err        error
}

var lzwTests = []lzwTest{
	{
		"empty;LSB;8",
		"",
		"\x01\x01",
		nil,
	},
	{
		"empty;MSB;8",
		"",
		"\x80\x80",
		nil,
	},
	{
		"tobe;LSB;7",
		"TOBEORNOTTOBEORTOBEORNOT",
		"\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
		nil,
	},
	{
		"tobe;LSB;8",
		"TOBEORNOTTOBEORTOBEORNOT",
		"\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04\x12\x34\xb8\xb0\xe0\xc1\x84\x01\x01",
		nil,
	},
	{
		"tobe;MSB;7",
		"TOBEORNOTTOBEORTOBEORNOT",
		"\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
		nil,
	},
	{
		"tobe;MSB;8",
		"TOBEORNOTTOBEORTOBEORNOT",
		"\x2a\x13\xc8\x44\x52\x79\x48\x9c\x4f\x2a\x40\xa0\x90\x68\x5c\x16\x0f\x09\x80\x80",
		nil,
	},
	{
		"tobe-truncated;LSB;8",
		"TOBEORNOTTOBEORTOBEORNOT",
		"\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04",
		io.ErrUnexpectedEOF,
	},
	// This example comes from http://en.wikipedia.org/wiki/Graphics_Interchange_Format.
	{
		"gif;LSB;8",
		"\x28\xff\xff\xff\x28\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
		"\x00\x51\xfc\x1b\x28\x70\xa0\xc1\x83\x01\x01",
		nil,
	},
	// This example comes from http://compgroups.net/comp.lang.ruby/Decompressing-LZW-compression-from-PDF-file
	{
		"pdf;MSB;8",
		"-----A---B",
		"\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01",
		nil,
	},
}

func TestReader(t *testing.T) {
	var b bytes.Buffer
	for _, tt := range lzwTests {
		d := strings.Split(tt.desc, ";")
		var order Order
		switch d[1] {
		case "LSB":
			order = LSB
		case "MSB":
			order = MSB
		default:
			t.Errorf("%s: bad order %q", tt.desc, d[1])
		}
		litWidth, _ := strconv.Atoi(d[2])
		rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
		defer rc.Close()
		b.Reset()
		n, err := io.Copy(&b, rc)
		if err != nil {
			if err != tt.err {
				t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
			}
			continue
		}
		s := b.String()
		if s != tt.raw {
			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
		}
	}
}

func benchmarkDecoder(b *testing.B, n int) {
	b.StopTimer()
	b.SetBytes(int64(n))
	buf0, err := ioutil.ReadFile("../testdata/e.txt")
	if err != nil {
		b.Fatal(err)
	}
	if len(buf0) == 0 {
		b.Fatalf("test file has no data")
	}
	compressed := new(bytes.Buffer)
	w := NewWriter(compressed, LSB, 8)
	for i := 0; i < n; i += len(buf0) {
		if len(buf0) > n-i {
			buf0 = buf0[:n-i]
		}
		w.Write(buf0)
	}
	w.Close()
	buf1 := compressed.Bytes()
	buf0, compressed, w = nil, nil, nil
	runtime.GC()
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1), LSB, 8))
	}
}

func BenchmarkDecoder1e4(b *testing.B) {
	benchmarkDecoder(b, 1e4)
}

func BenchmarkDecoder1e5(b *testing.B) {
	benchmarkDecoder(b, 1e5)
}

func BenchmarkDecoder1e6(b *testing.B) {
	benchmarkDecoder(b, 1e6)
}
