// 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"
pub status "#truncated input"

// 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!(key: base.u32, value: base.u64) base.status {
    if this.header_complete {
        this.bad_call_sequence = true
        return base."#bad call sequence"
    } else if args.key == base.QUIRK_IGNORE_CHECKSUM {
        this.ignore_checksum = args.value > 0
        return ok
    } else if args.key >= QUIRKS_BASE {
        args.key -= QUIRKS_BASE
        if args.key < QUIRKS_COUNT {
            this.quirks[args.key] = args.value > 0
            return ok
        }
    }
    return base."#unsupported option"
}

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 status : base.status

    while true {
        status =? this.do_transform_io?(dst: args.dst, src: args.src, workbuf: args.workbuf)
        if (status == base."$short read") and args.src.is_closed() {
            return "#truncated input"
        }
        yield? status
    } endwhile
}

pri func decoder.do_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?
}
