// 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[..= 12_582912]  // 12_582912 = (3 << 22)
	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 < 0x300 {  // 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 == 0x300 {  // 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 as base.u32) & 3) << 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
}
