// Copyright 2022 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pri func decoder.decode_huffman_slow?(src: base.io_reader) {
	var c          : base.u8
	var node_index : base.u32[..= 256]

	var child    : base.u16
	var child_ff : base.u32[..= 255]
	var i        : base.u32
	var j        : base.u32
	var output   : base.u32[..= 255]
	var run      : base.u32[..= 16_777216]  // 16_777216 = (2 << 23)
	var mtft0    : base.u32[..= 255]

	// Apply the Huffman trees.
	while.outer not coroutine_resumed {
		if this.decode_huffman_ticks > 0 {
			this.decode_huffman_ticks -= 1
		} else {
			this.decode_huffman_ticks = 49
			this.decode_huffman_section ~mod+= 1
			if this.decode_huffman_section >= this.num_sections {
				return "#bad number of sections"
			}
			this.decode_huffman_which = CLAMP_TO_5[this.huffman_selectors[this.decode_huffman_section & 32767] & 7]
		}

		node_index = 0
		while true {
			if this.n_bits <= 0 {
				c = args.src.read_u8?()
				this.bits = (c as base.u32) << 24
				this.n_bits = 8
				assert this.n_bits > 0
			}
			child = this.huffman_trees[this.decode_huffman_which][node_index][this.bits >> 31]
			this.bits ~mod<<= 1
			this.n_bits -= 1

			if child < 257 {  // Branch node.
				node_index = child as base.u32
				continue

			} else if child < 1280 {  // mNN symbol.
				// Move to front.
				child_ff = (child & 0xFF) as base.u32
				output = this.mtft[child_ff] as base.u32
				this.mtft[1 .. 1 + child_ff].copy_from_slice!(
					s: this.mtft[.. child_ff])
				this.mtft[0] = output as base.u8

				this.letter_counts[output] ~mod+= 1
				this.bwt[this.block_size] = output
				if this.block_size >= this.max_incl_block_size {
					return "#bad block length"
				}
				assert this.block_size < 900000 via "a < b: a < c; c <= b"(c: this.max_incl_block_size)
				this.block_size += 1
				this.decode_huffman_run_shift = 0
				break

			} else if child > 1281 {  // EOB symbol.
				this.decode_huffman_finished = true
				break.outer
			}

			// RUNA or RUNB symbol.
			if this.decode_huffman_run_shift >= 23 {
				return "#bad block length"
			}
			run = ((child - 1279) as base.u32) << this.decode_huffman_run_shift
			this.decode_huffman_run_shift += 1
			i = this.block_size
			j = run + this.block_size
			if j > this.max_incl_block_size {
				return "#bad block length"
			}
			assert j <= 900000 via "a <= b: a <= c; c <= b"(c: this.max_incl_block_size)
			this.block_size = j

			mtft0 = this.mtft[0] as base.u32
			this.letter_counts[mtft0] ~mod+= run
			while i < j,
				pre j <= 900000,
			{
				assert i < 900000 via "a < b: a < c; c <= b"(c: j)
				this.bwt[i] = mtft0
				i += 1
			} endwhile
			break
		} endwhile
	} endwhile.outer
}
