// 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 compressor looks for
	maxMatchLength       = 258 // The longest match for the compressor
	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 compressor 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 *compressor) flush() os.Error {
	d.w.flush()
	return d.w.err
}

func (d *compressor) 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 *compressor) 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 *compressor) 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 *compressor) 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 *compressor) 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 *compressor) 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 *compressor) compressor(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 newCompressor(w io.Writer, level int, logWindowSize uint) io.WriteCloser {
	var d compressor
	pr, pw := syncPipe()
	go func() {
		err := d.compressor(pr, w, level, logWindowSize)
		pr.CloseWithError(err)
	}()
	return pw
}

func NewWriter(w io.Writer, level int) io.WriteCloser {
	return newCompressor(w, level, logMaxOffsetSize)
}
