// Copyright 2023 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 zstd

import (
	
	
)

// maxHuffmanBits is the largest possible Huffman table bits.
const maxHuffmanBits = 11

// readHuff reads Huffman table from data starting at off into table.
// Each entry in a Huffman table is a pair of bytes.
// The high byte is the encoded value. The low byte is the number
// of bits used to encode that value. We index into the table
// with a value of size tableBits. A value that requires fewer bits
// appear in the table multiple times.
// This returns the number of bits in the Huffman table and the new offset.
// RFC 4.2.1.
func ( *Reader) ( block,  int,  []uint16) (,  int,  error) {
	if  >= len() {
		return 0, 0, .makeEOFError()
	}

	 := []
	++

	var  [256]uint8
	var  int
	if  < 128 {
		// The table is compressed using an FSE. RFC 4.2.1.2.
		if len(.fseScratch) < 1<<6 {
			.fseScratch = make([]fseEntry, 1<<6)
		}
		, ,  := .readFSE(, , 255, 6, .fseScratch)
		if  != nil {
			return 0, 0, 
		}
		 := .fseScratch

		if +int() > len() {
			return 0, 0, .makeEOFError()
		}

		,  := .makeReverseBitReader(, +int()-1, )
		if  != nil {
			return 0, 0, 
		}

		,  := .val(uint8())
		if  != nil {
			return 0, 0, 
		}

		,  := .val(uint8())
		if  != nil {
			return 0, 0, 
		}

		// There are two independent FSE streams, tracked by
		// state1 and state2. We decode them alternately.

		for {
			 := &[]
			if !.fetch(.bits) {
				if  >= 254 {
					return 0, 0, .makeError("Huffman count overflow")
				}
				[] = .sym
				[+1] = [].sym
				 += 2
				break
			}

			,  := .val(.bits)
			if  != nil {
				return 0, 0, 
			}
			 = uint32(.base) + 

			if  >= 255 {
				return 0, 0, .makeError("Huffman count overflow")
			}

			[] = .sym
			++

			 = &[]

			if !.fetch(.bits) {
				if  >= 254 {
					return 0, 0, .makeError("Huffman count overflow")
				}
				[] = .sym
				[+1] = [].sym
				 += 2
				break
			}

			,  = .val(.bits)
			if  != nil {
				return 0, 0, 
			}
			 = uint32(.base) + 

			if  >= 255 {
				return 0, 0, .makeError("Huffman count overflow")
			}

			[] = .sym
			++
		}

		 += int()
	} else {
		// The table is not compressed. Each weight is 4 bits.

		 = int() - 127
		if +((+1)/2) >= len() {
			return 0, 0, io.ErrUnexpectedEOF
		}
		for  := 0;  < ;  += 2 {
			 := []
			++
			[] =  >> 4
			[+1] =  & 0xf
		}
	}

	// RFC 4.2.1.3.

	var  [13]uint32
	 := uint32(0)
	for ,  := range [:] {
		if  > 12 {
			return 0, 0, .makeError(, "Huffman weight overflow")
		}
		[]++
		if  > 0 {
			 += 1 << ( - 1)
		}
	}
	if  == 0 {
		return 0, 0, .makeError(, "bad Huffman weights")
	}

	 = 32 - bits.LeadingZeros32()
	if  > maxHuffmanBits {
		return 0, 0, .makeError(, "bad Huffman weights")
	}

	if len() < 1<< {
		return 0, 0, .makeError(, "Huffman table too small")
	}

	// Work out the last weight value, which is omitted because
	// the weights must sum to a power of two.
	 := (uint32(1) << ) - 
	if  == 0 {
		return 0, 0, .makeError(, "bad Huffman weights")
	}
	 := 31 - bits.LeadingZeros32()
	if uint32(1)<< !=  {
		return 0, 0, .makeError(, "bad Huffman weights")
	}
	if  >= 256 {
		return 0, 0, .makeError(, "Huffman weight overflow")
	}
	[] = uint8( + 1)
	++
	[+1]++

	if [1] < 2 || [1]&1 != 0 {
		return 0, 0, .makeError(, "bad Huffman weights")
	}

	// Change weightMark from a count of weights to the index of
	// the first symbol for that weight. We shift the indexes to
	// also store how many we have seen so far,
	 := uint32(0)
	for  := 0;  < ; ++ {
		 := 
		 += [+1] << 
		[+1] = 
	}

	for ,  := range [:] {
		if  == 0 {
			continue
		}
		 := uint32(1) << ( - 1)
		 := uint16()<<8 | (uint16() + 1 - uint16())
		 := []
		for  := uint32(0);  < ; ++ {
			[+] = 
		}
		[] += 
	}

	return , , nil
}