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

import (
	"bytes";
	"io";
	"math";
	"os";
)

const (
	NoCompression		= 0;
	BestSpeed		= 1;
	fastCompression		= 3;
	BestCompression		= 9;
	DefaultCompression	= -1;
	logMaxOffsetSize	= 15;	// Standard DEFLATE
	wideLogMaxOffsetSize	= 22;	// Wide DEFLATE
	minMatchLength		= 3;	// The smallest match that the deflater looks for
	maxMatchLength		= 258;	// The longest match for the deflater
	minOffsetSize		= 1;	// The shortest offset that makes any sence

	// The maximum number of tokens we put into a single flat block, just too
	// stop things from getting too large.
	maxFlateBlockTokens	= 1 << 14;
	maxStoreBlockSize	= 65535;
	hashBits		= 15;
	hashSize		= 1 << hashBits;
	hashMask		= (1 << hashBits) - 1;
	hashShift		= (hashBits + minMatchLength - 1) / minMatchLength;
)

type syncPipeReader struct {
	*io.PipeReader;
	closeChan	chan bool;
}

func (sr *syncPipeReader) CloseWithError(err os.Error) os.Error {
	retErr := sr.PipeReader.CloseWithError(err);
	sr.closeChan <- true;	// finish writer close
	return retErr;
}

type syncPipeWriter struct {
	*io.PipeWriter;
	closeChan	chan bool;
}

type compressionLevel struct {
	good, lazy, nice, chain, fastSkipHashing int;
}

var levels = []compressionLevel{
	compressionLevel{},	// 0
	// For levels 1-3 we don't bother trying with lazy matches
	compressionLevel{3, 0, 8, 4, 4},
	compressionLevel{3, 0, 16, 8, 5},
	compressionLevel{3, 0, 32, 32, 6},
	// Levels 4-9 use increasingly more lazy matching
	// and increasingly stringent conditions for "good enough".
	compressionLevel{4, 4, 16, 16, math.MaxInt32},
	compressionLevel{8, 16, 32, 32, math.MaxInt32},
	compressionLevel{8, 16, 128, 128, math.MaxInt32},
	compressionLevel{8, 32, 128, 256, math.MaxInt32},
	compressionLevel{32, 128, 258, 1024, math.MaxInt32},
	compressionLevel{32, 258, 258, 4096, math.MaxInt32},
}

func (sw *syncPipeWriter) Close() os.Error {
	err := sw.PipeWriter.Close();
	<-sw.closeChan;	// wait for reader close
	return err;
}

func syncPipe() (*syncPipeReader, *syncPipeWriter) {
	r, w := io.Pipe();
	sr := &syncPipeReader{r, make(chan bool, 1)};
	sw := &syncPipeWriter{w, sr.closeChan};
	return sr, sw;
}

type deflater struct {
	level		int;
	logWindowSize	uint;
	w		*huffmanBitWriter;
	r		io.Reader;
	// (1 << logWindowSize) - 1.
	windowMask	int;

	// hashHead[hashValue] contains the largest inputIndex with the specified hash value
	hashHead	[]int;

	// If hashHead[hashValue] is within the current window, then
	// hashPrev[hashHead[hashValue] & windowMask] contains the previous index
	// with the same hash value.
	hashPrev	[]int;

	// If we find a match of length >= niceMatch, then we don't bother searching
	// any further.
	niceMatch	int;

	// If we find a match of length >= goodMatch, we only do a half-hearted
	// effort at doing lazy matching starting at the next character
	goodMatch	int;

	// The maximum number of chains we look at when finding a match
	maxChainLength	int;

	// The sliding window we use for matching
	window	[]byte;

	// The index just past the last valid character
	windowEnd	int;

	// index in "window" at which current block starts
	blockStart	int;
}

func (d *deflater) flush() os.Error {
	d.w.flush();
	return d.w.err;
}

func (d *deflater) fillWindow(index int) (int, os.Error) {
	wSize := d.windowMask + 1;
	if index >= wSize+wSize-(minMatchLength+maxMatchLength) {
		// shift the window by wSize
		bytes.Copy(d.window, d.window[wSize:2*wSize]);
		index -= wSize;
		d.windowEnd -= wSize;
		if d.blockStart >= wSize {
			d.blockStart -= wSize
		} else {
			d.blockStart = math.MaxInt32
		}
		for i, h := range d.hashHead {
			d.hashHead[i] = max(h-wSize, -1)
		}
		for i, h := range d.hashPrev {
			d.hashPrev[i] = max(h-wSize, -1)
		}
	}
	var count int;
	var err os.Error;
	count, err = io.ReadAtLeast(d.r, d.window[d.windowEnd:len(d.window)], 1);
	d.windowEnd += count;
	if err == os.EOF {
		return index, nil
	}
	return index, err;
}

func (d *deflater) writeBlock(tokens []token, index int, eof bool) os.Error {
	if index > 0 || eof {
		var window []byte;
		if d.blockStart <= index {
			window = d.window[d.blockStart:index]
		}
		d.blockStart = index;
		d.w.writeBlock(tokens, eof, window);
		return d.w.err;
	}
	return nil;
}

// Try to find a match starting at index whose length is greater than prevSize.
// We only look at chainCount possibilities before giving up.
func (d *deflater) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
	win := d.window[0 : pos+min(maxMatchLength, lookahead)];

	// We quit when we get a match that's at least nice long
	nice := min(d.niceMatch, len(win)-pos);

	// If we've got a match that's good enough, only look in 1/4 the chain.
	tries := d.maxChainLength;
	length = prevLength;
	if length >= d.goodMatch {
		tries >>= 2
	}

	w0 := win[pos];
	w1 := win[pos+1];
	wEnd := win[pos+length];
	minIndex := pos - (d.windowMask + 1);

	for i := prevHead; tries > 0; tries-- {
		if w0 == win[i] && w1 == win[i+1] && wEnd == win[i+length] {
			// The hash function ensures that if win[i] and win[i+1] match, win[i+2] matches

			n := 3;
			for pos+n < len(win) && win[i+n] == win[pos+n] {
				n++
			}
			if n > length && (n > 3 || pos-i <= 4096) {
				length = n;
				offset = pos - i;
				ok = true;
				if n >= nice {
					// The match is good enough that we don't try to find a better one.
					break
				}
				wEnd = win[pos+n];
			}
		}
		if i == minIndex {
			// hashPrev[i & windowMask] has already been overwritten, so stop now.
			break
		}
		if i = d.hashPrev[i&d.windowMask]; i < minIndex || i < 0 {
			break
		}
	}
	return;
}

func (d *deflater) writeStoredBlock(buf []byte) os.Error {
	if d.w.writeStoredHeader(len(buf), false); d.w.err != nil {
		return d.w.err
	}
	d.w.writeBytes(buf);
	return d.w.err;
}

func (d *deflater) storedDeflate() os.Error {
	buf := make([]byte, maxStoreBlockSize);
	for {
		n, err := d.r.Read(buf);
		if n > 0 {
			if err := d.writeStoredBlock(buf[0:n]); err != nil {
				return err
			}
		}
		if err != nil {
			if err == os.EOF {
				break
			}
			return err;
		}
	}
	return nil;
}

func (d *deflater) doDeflate() (err os.Error) {
	// init
	d.windowMask = 1<<d.logWindowSize - 1;
	d.hashHead = make([]int, hashSize);
	d.hashPrev = make([]int, 1<<d.logWindowSize);
	d.window = make([]byte, 2<<d.logWindowSize);
	fillInts(d.hashHead, -1);
	tokens := make([]token, maxFlateBlockTokens, maxFlateBlockTokens+1);
	l := levels[d.level];
	d.goodMatch = l.good;
	d.niceMatch = l.nice;
	d.maxChainLength = l.chain;
	lazyMatch := l.lazy;
	length := minMatchLength - 1;
	offset := 0;
	byteAvailable := false;
	isFastDeflate := l.fastSkipHashing != 0;
	index := 0;
	// run
	if index, err = d.fillWindow(index); err != nil {
		return
	}
	maxOffset := d.windowMask + 1;	// (1 << logWindowSize);
	// only need to change when you refill the window
	windowEnd := d.windowEnd;
	maxInsertIndex := windowEnd - (minMatchLength - 1);
	ti := 0;

	hash := int(0);
	if index < maxInsertIndex {
		hash = int(d.window[index])<<hashShift + int(d.window[index+1])
	}
	chainHead := -1;
	for {
		if index > windowEnd {
			panic("index > windowEnd")
		}
		lookahead := windowEnd - index;
		if lookahead < minMatchLength+maxMatchLength {
			if index, err = d.fillWindow(index); err != nil {
				return
			}
			windowEnd = d.windowEnd;
			if index > windowEnd {
				panic("index > windowEnd")
			}
			maxInsertIndex = windowEnd - (minMatchLength - 1);
			lookahead = windowEnd - index;
			if lookahead == 0 {
				break
			}
		}
		if index < maxInsertIndex {
			// Update the hash
			hash = (hash<<hashShift + int(d.window[index+2])) & hashMask;
			chainHead = d.hashHead[hash];
			d.hashPrev[index&d.windowMask] = chainHead;
			d.hashHead[hash] = index;
		}
		prevLength := length;
		prevOffset := offset;
		minIndex := max(index-maxOffset, 0);
		length = minMatchLength - 1;
		offset = 0;

		if chainHead >= minIndex &&
			(isFastDeflate && lookahead > minMatchLength-1 ||
				!isFastDeflate && lookahead > prevLength && prevLength < lazyMatch) {
			if newLength, newOffset, ok := d.findMatch(index, chainHead, minMatchLength-1, lookahead); ok {
				length = newLength;
				offset = newOffset;
			}
		}
		if isFastDeflate && length >= minMatchLength ||
			!isFastDeflate && prevLength >= minMatchLength && length <= prevLength {
			// There was a match at the previous step, and the current match is
			// not better. Output the previous match.
			if isFastDeflate {
				tokens[ti] = matchToken(uint32(length-minMatchLength), uint32(offset-minOffsetSize))
			} else {
				tokens[ti] = matchToken(uint32(prevLength-minMatchLength), uint32(prevOffset-minOffsetSize))
			}
			ti++;
			// Insert in the hash table all strings up to the end of the match.
			// index and index-1 are already inserted. If there is not enough
			// lookahead, the last two strings are not inserted into the hash
			// table.
			if length <= l.fastSkipHashing {
				var newIndex int;
				if isFastDeflate {
					newIndex = index + length
				} else {
					newIndex = prevLength - 1
				}
				for index++; index < newIndex; index++ {
					if index < maxInsertIndex {
						hash = (hash<<hashShift + int(d.window[index+2])) & hashMask;
						// Get previous value with the same hash.
						// Our chain should point to the previous value.
						d.hashPrev[index&d.windowMask] = d.hashHead[hash];
						// Set the head of the hash chain to us.
						d.hashHead[hash] = index;
					}
				}
				if !isFastDeflate {
					byteAvailable = false;
					length = minMatchLength - 1;
				}
			} else {
				// For matches this long, we don't bother inserting each individual
				// item into the table.
				index += length;
				hash = (int(d.window[index]) << hashShift + int(d.window[index+1]));
			}
			if ti == maxFlateBlockTokens {
				// The block includes the current character
				if err = d.writeBlock(tokens, index, false); err != nil {
					return
				}
				ti = 0;
			}
		} else {
			if isFastDeflate || byteAvailable {
				i := index - 1;
				if isFastDeflate {
					i = index
				}
				tokens[ti] = literalToken(uint32(d.window[i]) & 0xFF);
				ti++;
				if ti == maxFlateBlockTokens {
					if err = d.writeBlock(tokens, i+1, false); err != nil {
						return
					}
					ti = 0;
				}
			}
			index++;
			if !isFastDeflate {
				byteAvailable = true
			}
		}

	}
	if byteAvailable {
		// There is still one pending token that needs to be flushed
		tokens[ti] = literalToken(uint32(d.window[index-1]) & 0xFF);
		ti++;
	}

	if ti > 0 {
		if err = d.writeBlock(tokens[0:ti], index, false); err != nil {
			return
		}
	}
	return;
}

func (d *deflater) deflater(r io.Reader, w io.Writer, level int, logWindowSize uint) (err os.Error) {
	d.r = r;
	d.w = newHuffmanBitWriter(w);
	d.level = level;
	d.logWindowSize = logWindowSize;

	switch {
	case level == NoCompression:
		err = d.storedDeflate()
	case level == DefaultCompression:
		d.level = 6;
		fallthrough;
	case 1 <= level && level <= 9:
		err = d.doDeflate()
	default:
		return WrongValueError{"level", 0, 9, int32(level)}
	}

	if err != nil {
		return err
	}
	if d.w.writeStoredHeader(0, true); d.w.err != nil {
		return d.w.err
	}
	return d.flush();
}

func newDeflater(w io.Writer, level int, logWindowSize uint) io.WriteCloser {
	var d deflater;
	pr, pw := syncPipe();
	go func() {
		err := d.deflater(pr, w, level, logWindowSize);
		pr.CloseWithError(err);
	}();
	return pw;
}

func NewDeflater(w io.Writer, level int) io.WriteCloser {
	return newDeflater(w, level, logMaxOffsetSize)
}
