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

// This test tests some internals of the flate package.
// The tests in package compress/gzip serve as the
// end-to-end test of the inflater.

package flate

import (
	"bytes";
	"reflect";
	"testing";
)

// The Huffman code lengths used by the fixed-format Huffman blocks.
var fixedHuffmanBits = [...]int{
	// 0-143 length 8
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

	// 144-255 length 9
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,

	// 256-279 length 7
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	7, 7, 7, 7, 7, 7, 7, 7,

	// 280-287 length 8
	8, 8, 8, 8, 8, 8, 8, 8,
}

type InitDecoderTest struct {
	in	[]int;
	out	huffmanDecoder;
	ok	bool;
}

var initDecoderTests = []*InitDecoderTest{
	// Example from Connell 1973,
	&InitDecoderTest{
		[]int{3, 5, 2, 4, 3, 5, 5, 4, 4, 3, 4, 5},
		huffmanDecoder{
			2, 5,
			[maxCodeLen + 1]int{2: 0, 4, 13, 31},
			[maxCodeLen + 1]int{2: 0, 1, 6, 20},
			// Paper used different code assignment:
			// 2, 9, 4, 0, 10, 8, 3, 7, 1, 5, 11, 6
			// Reordered here so that codes of same length
			// are assigned to increasing numbers.
			[]int{2, 0, 4, 9, 3, 7, 8, 10, 1, 5, 6, 11},
		},
		true,
	},

	// Example from RFC 1951 section 3.2.2
	&InitDecoderTest{
		[]int{2, 1, 3, 3},
		huffmanDecoder{
			1, 3,
			[maxCodeLen + 1]int{1: 0, 2, 7},
			[maxCodeLen + 1]int{1: 0, 1, 4},
			[]int{1, 0, 2, 3},
		},
		true,
	},

	// Second example from RFC 1951 section 3.2.2
	&InitDecoderTest{
		[]int{3, 3, 3, 3, 3, 2, 4, 4},
		huffmanDecoder{
			2, 4,
			[maxCodeLen + 1]int{2: 0, 6, 15},
			[maxCodeLen + 1]int{2: 0, 1, 8},
			[]int{5, 0, 1, 2, 3, 4, 6, 7},
		},
		true,
	},

	// Static Huffman codes (RFC 1951 section 3.2.6)
	&InitDecoderTest{
		&fixedHuffmanBits,
		fixedHuffmanDecoder,
		true,
	},

	// Illegal input.
	&InitDecoderTest{
		[]int{},
		huffmanDecoder{},
		false,
	},

	// Illegal input.
	&InitDecoderTest{
		[]int{0, 0, 0, 0, 0, 0, 0},
		huffmanDecoder{},
		false,
	},
}

func TestInitDecoder(t *testing.T) {
	for i, tt := range initDecoderTests {
		var h huffmanDecoder;
		if h.init(tt.in) != tt.ok {
			t.Errorf("test %d: init = %v", i, !tt.ok);
			continue;
		}
		if !reflect.DeepEqual(&h, &tt.out) {
			t.Errorf("test %d:\nhave %v\nwant %v", i, h, tt.out)
		}
	}
}

func TestUncompressedSource(t *testing.T) {
	decoder := NewInflater(bytes.NewBuffer([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}));
	output := make([]byte, 1);
	n, error := decoder.Read(output);
	if n != 1 || error != nil {
		t.Fatalf("decoder.Read() = %d, %v, want 1, nil", n, error)
	}
	if output[0] != 0x11 {
		t.Errorf("output[0] = %x, want 0x11", output[0])
	}
}
