// 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 (
	"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
		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:], 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)
}
