// Copyright 2017 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.

use "std/adler32"
use "std/deflate"

pub status "@dictionary required"

pub status "#bad checksum"
pub status "#bad compression method"
pub status "#bad compression window size"
pub status "#bad parity check"
pub status "#incorrect dictionary"

// TODO: reference deflate.DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE.
pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 1

pub struct decoder? implements base.io_transformer(
	bad_call_sequence : base.bool,
	header_complete   : base.bool,

	got_dictionary  : base.bool,
	want_dictionary : base.bool,

	quirks : array[QUIRKS_COUNT] base.bool,

	ignore_checksum : base.bool,
	checksum        : adler32.hasher,

	dict_id_hasher : adler32.hasher,
	dict_id_got    : base.u32,
	dict_id_want   : base.u32,

	flate : deflate.decoder,

	util : base.utility,
)

pub func decoder.dictionary_id() base.u32 {
	return this.dict_id_want
}

pub func decoder.add_dictionary!(dict: slice base.u8) {
	if this.header_complete {
		this.bad_call_sequence = true
	} else {
		this.dict_id_got = this.dict_id_hasher.update_u32!(x: args.dict)
		this.flate.add_history!(hist: args.dict)
	}
	this.got_dictionary = true
}

pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
	if this.header_complete {
		this.bad_call_sequence = true
	} else if args.quirk == base.QUIRK_IGNORE_CHECKSUM {
		this.ignore_checksum = args.enabled
	} else if args.quirk >= QUIRKS_BASE {
		args.quirk -= QUIRKS_BASE
		if args.quirk < QUIRKS_COUNT {
			this.quirks[args.quirk] = args.enabled
		}
	}
}

pub func decoder.workbuf_len() base.range_ii_u64 {
	return this.util.make_range_ii_u64(
		min_incl: DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE,
		max_incl: DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE)
}

pub func decoder.transform_io?(dst: base.io_writer, src: base.io_reader, workbuf: slice base.u8) {
	var x             : base.u16
	var checksum_got  : base.u32
	var status        : base.status
	var checksum_want : base.u32
	var mark          : base.u64

	if this.bad_call_sequence {
		return base."#bad call sequence"
	} else if this.quirks[QUIRK_JUST_RAW_DEFLATE - QUIRKS_BASE] {
		// No-op.
	} else if not this.want_dictionary {
		x = args.src.read_u16be?()
		if ((x >> 8) & 0x0F) <> 0x08 {
			return "#bad compression method"
		}
		if (x >> 12) > 0x07 {
			return "#bad compression window size"
		}
		if (x % 31) <> 0 {
			return "#bad parity check"
		}
		this.want_dictionary = (x & 0x20) <> 0
		if this.want_dictionary {
			this.dict_id_got = 1  // Adler-32 initial value.
			this.dict_id_want = args.src.read_u32be?()
			return "@dictionary required"
		} else if this.got_dictionary {
			return "#incorrect dictionary"
		}
	} else if this.dict_id_got <> this.dict_id_want {
		if this.got_dictionary {
			return "#incorrect dictionary"
		}
		return "@dictionary required"
	}

	this.header_complete = true

	// Decode and checksum the DEFLATE-encoded payload.
	while true {
		mark = args.dst.mark()
		status =? this.flate.transform_io?(dst: args.dst, src: args.src, workbuf: args.workbuf)
		if (not this.ignore_checksum) and (not this.quirks[QUIRK_JUST_RAW_DEFLATE - QUIRKS_BASE]) {
			checksum_got = this.checksum.update_u32!(x: args.dst.since(mark: mark))
		}
		if status.is_ok() {
			break
		}
		yield? status
	} endwhile

	if not this.quirks[QUIRK_JUST_RAW_DEFLATE - QUIRKS_BASE] {
		checksum_want = args.src.read_u32be?()
		if (not this.ignore_checksum) and (checksum_got <> checksum_want) {
			return "#bad checksum"
		}
	}

	// TODO: reset state (e.g. want_dictionary), so that we can read concat'ed
	// zlib streams?
}
