// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

pub status "#bad frame"
pub status "#bad header"
pub status "#truncated input"
pub status "#unsupported restart frame index"

pri status "@internal note: short read"

pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0

pub struct decoder? implements base.image_decoder(
        pixfmt : base.u32,
        width  : base.u32[..= 0xFF_FFFF],
        height : base.u32[..= 0xFF_FFFF],

        // The call sequence state machine is discussed in
        // (/doc/std/image-decoders-call-sequence.md).
        call_sequence : base.u8,

        animated : base.bool,

        nie_config : base.u32,

        num_animation_loops_value : base.u32,

        prev_duration : base.u64[..= 0x7FFF_FFFF_FFFF_FFFF],
        curr_duration : base.u64[..= 0x7FFF_FFFF_FFFF_FFFF],

        num_decoded_frame_configs_value : base.u64,
        num_decoded_frames_value        : base.u64,

        dst_x : base.u32,
        dst_y : base.u32,

        swizzler : base.pixel_swizzler,
        util     : base.utility,
)

pub func decoder.get_quirk(key: base.u32) base.u64 {
    return 0
}

pub func decoder.set_quirk!(key: base.u32, value: base.u64) base.status {
    return base."#unsupported option"
}

pub func decoder.decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
    var status : base.status

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

pri func decoder.do_decode_image_config?(dst: nptr base.image_config, src: base.io_reader) {
    var a : base.u32

    if this.call_sequence <> 0x00 {
        return base."#bad call sequence"
    }

    a = args.src.read_u32le?()
    if a == 'nïA'le {
        this.animated = true
    } else if a == 'nïE'le {
        this.animated = false
    } else {
        return "#bad header"
    }

    a = args.src.read_u32le?()
    if a == '\xFFbn4'le {
        this.pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL
    } else if a == '\xFFbn8'le {
        this.pixfmt = base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
    } else if a == '\xFFbp4'le {
        this.pixfmt = base.PIXEL_FORMAT__BGRA_PREMUL
    } else if a == '\xFFbp8'le {
        this.pixfmt = base.PIXEL_FORMAT__BGRA_PREMUL_4X16LE
    } else {
        return "#bad header"
    }
    this.nie_config = a

    a = args.src.read_u32le?()
    if a > 0x7FFF_FFFF {
        return "#bad header"
    } else if a > 0xFF_FFFF {
        return base."#unsupported image dimension"
    }
    this.width = a

    a = args.src.read_u32le?()
    if a > 0x7FFF_FFFF {
        return "#bad header"
    } else if a > 0xFF_FFFF {
        return base."#unsupported image dimension"
    }
    this.height = a

    if args.dst <> nullptr {
        args.dst.set!(
                pixfmt: this.pixfmt,
                pixsub: 0,
                width: this.width,
                height: this.height,
                first_frame_io_position: 16,
                first_frame_is_opaque: false)
    }

    this.call_sequence = 0x20
}

pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
    var status : base.status

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

pri func decoder.do_decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
    var pixfmt      : base.pixel_format
    var io_position : base.u64

    if this.call_sequence == 0x20 {
        // No-op.
    } else if this.call_sequence < 0x20 {
        this.do_decode_image_config?(dst: nullptr, src: args.src)
    } else if this.call_sequence == 0x28 {
        if 16 <> args.src.position() {
            return base."#bad restart"
        }
    } else if this.call_sequence == 0x40 {
        this.skip_frame?(src: args.src)
    } else {
        return base."@end of data"
    }

    if this.animated {
        this.decode_animation_info?(src: args.src)
    }

    if args.dst <> nullptr {
        io_position = args.src.position()
        if this.animated {
            io_position ~sat-= 24
        }

        pixfmt = this.util.make_pixel_format(repr: this.pixfmt)
        args.dst.set!(bounds: this.util.make_rect_ie_u32(
                min_incl_x: 0,
                min_incl_y: 0,
                max_excl_x: this.width,
                max_excl_y: this.height),
                duration: this.curr_duration ~sat- this.prev_duration,
                index: this.num_decoded_frame_configs_value,
                io_position: io_position,
                disposal: 0,
                opaque_within_bounds: false,
                overwrite_instead_of_blend: false,
                background_color: pixfmt.default_background_color())
    }

    this.num_decoded_frame_configs_value ~sat+= 1
    this.call_sequence = 0x40
}

pri func decoder.decode_animation_info?(src: base.io_reader) {
    var c32 : base.u32
    var c64 : base.u64

    c64 = args.src.read_u64le?()
    if c64 < 0x8000_0000_0000_0000 {
        if c64 < this.curr_duration {
            return "#bad frame"
        }
        this.prev_duration = this.curr_duration
        this.curr_duration = c64

    } else if (c64 >> 32) == 0x8000_0000 {
        this.call_sequence = 0x60
        this.num_animation_loops_value = (c64 & 0xFFFF_FFFF) as base.u32
        return base."@end of data"

    } else {
        return "#bad frame"
    }

    c32 = args.src.read_u32le?()
    if c32 <> 'nïE'le {
        return "#bad frame"
    }

    c32 = args.src.read_u32le?()
    if c32 <> this.nie_config {
        return "#bad frame"
    }

    c32 = args.src.read_u32le?()
    if c32 <> this.width {
        return "#bad frame"
    }

    c32 = args.src.read_u32le?()
    if c32 <> this.height {
        return "#bad frame"
    }
}

pri func decoder.skip_frame?(src: base.io_reader) {
    var src_bytes_per_pixel : base.u64[..= 8]

    if (this.pixfmt == base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE) or
            (this.pixfmt == base.PIXEL_FORMAT__BGRA_PREMUL_4X16LE) {
        src_bytes_per_pixel = 8
    } else {
        src_bytes_per_pixel = 4
    }

    args.src.skip?(n: src_bytes_per_pixel * (this.width as base.u64) * (this.height as base.u64))

    if this.animated {
        this.num_decoded_frames_value ~sat+= 1
        this.call_sequence = 0x20
    } else {
        this.num_decoded_frames_value ~sat+= 1
        this.call_sequence = 0x60
        return base."@end of data"
    }
}

pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
    var status : base.status

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

pri func decoder.do_decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
    var status : base.status
    var c64    : base.u64

    if this.call_sequence == 0x40 {
        // No-op.
    } else if this.call_sequence < 0x40 {
        this.do_decode_frame_config?(dst: nullptr, src: args.src)
    } else {
        return base."@end of data"
    }

    this.dst_x = 0
    this.dst_y = 0

    status = this.swizzler.prepare!(
            dst_pixfmt: args.dst.pixel_format(),
            dst_palette: args.dst.palette(),
            src_pixfmt: this.util.make_pixel_format(repr: this.pixfmt),
            src_palette: this.util.empty_slice_u8(),
            blend: args.blend)
    if not status.is_ok() {
        return status
    }

    while true {
        status = this.swizzle!(dst: args.dst, src: args.src)
        if status.is_ok() {
            break
        } else if status <> "@internal note: short read" {
            return status
        }
        yield? base."$short read"
    }

    if this.animated {
        // If the animation has N frames, we want decoder.num_animation_loops
        // to report the final value whether after (N+1) decode_frame_config
        // calls or after N decode_frame calls.
        while args.src.length() < 8,
                post args.src.length() >= 8,
        {
            yield? base."$short read"
        }
        c64 = args.src.peek_u64le()
        if (c64 >> 32) == 0x8000_0000 {
            this.num_animation_loops_value = (c64 & 0xFFFF_FFFF) as base.u32
        }

        this.num_decoded_frames_value ~sat+= 1
        this.call_sequence = 0x20
    } else {
        this.num_decoded_frames_value ~sat+= 1
        this.call_sequence = 0x60
    }
}

pri func decoder.swizzle!(dst: ptr base.pixel_buffer, src: base.io_reader) base.status {
    var dst_pixfmt          : base.pixel_format
    var dst_bits_per_pixel  : base.u32[..= 256]
    var dst_bytes_per_pixel : base.u32[..= 32]
    var dst_bytes_per_row   : base.u64
    var src_bytes_per_pixel : base.u32[..= 8]
    var tab                 : table base.u8
    var dst                 : slice base.u8
    var i                   : base.u64
    var j                   : base.u64
    var n                   : base.u64

    // TODO: the dst_pixfmt variable shouldn't be necessary. We should be able
    // to chain the two calls: "args.dst.pixel_format().bits_per_pixel()".
    dst_pixfmt = args.dst.pixel_format()
    dst_bits_per_pixel = dst_pixfmt.bits_per_pixel()
    if (dst_bits_per_pixel & 7) <> 0 {
        return base."#unsupported option"
    }
    dst_bytes_per_pixel = dst_bits_per_pixel / 8
    dst_bytes_per_row = (this.width * dst_bytes_per_pixel) as base.u64
    tab = args.dst.plane(p: 0)

    while true {
        if this.dst_x == this.width {
            this.dst_x = 0
            this.dst_y ~mod+= 1
            if this.dst_y >= this.height {
                break
            }
        }

        dst = tab.row_u32(y: this.dst_y)
        if dst_bytes_per_row < dst.length() {
            dst = dst[.. dst_bytes_per_row]
        }
        i = (this.dst_x as base.u64) * (dst_bytes_per_pixel as base.u64)
        if i >= dst.length() {
            src_bytes_per_pixel = 4
            assert src_bytes_per_pixel > 0
            if (this.pixfmt == base.PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE) or
                    (this.pixfmt == base.PIXEL_FORMAT__BGRA_PREMUL_4X16LE) {
                src_bytes_per_pixel = 8
                assert src_bytes_per_pixel > 0
            }
            n = args.src.length() / (src_bytes_per_pixel as base.u64)
            n = n.min(no_more_than: (this.width ~mod- this.dst_x) as base.u64)
            j = n
            while j >= 8 {
                if args.src.length() >= ((src_bytes_per_pixel * 8) as base.u64) {
                    args.src.skip_u32_fast!(
                            actual: src_bytes_per_pixel * 8,
                            worst_case: src_bytes_per_pixel * 8)
                }
                j -= 8
            }
            while j > 0 {
                if args.src.length() >= ((src_bytes_per_pixel * 1) as base.u64) {
                    args.src.skip_u32_fast!(
                            actual: src_bytes_per_pixel * 1,
                            worst_case: src_bytes_per_pixel * 1)
                }
                j -= 1
            }
        } else {
            n = this.swizzler.swizzle_interleaved_from_reader!(
                    dst: dst[i ..],
                    dst_palette: args.dst.palette(),
                    src: args.src)
        }
        if n == 0 {
            return "@internal note: short read"
        }
        this.dst_x ~sat+= (n & 0xFFFF_FFFF) as base.u32
    }

    return ok
}

pub func decoder.frame_dirty_rect() base.rect_ie_u32 {
    return this.util.make_rect_ie_u32(
            min_incl_x: 0,
            min_incl_y: 0,
            max_excl_x: this.width,
            max_excl_y: this.height)
}

pub func decoder.num_animation_loops() base.u32 {
    return this.num_animation_loops_value
}

pub func decoder.num_decoded_frame_configs() base.u64 {
    return this.num_decoded_frame_configs_value
}

pub func decoder.num_decoded_frames() base.u64 {
    return this.num_decoded_frames_value
}

pub func decoder.restart_frame!(index: base.u64, io_position: base.u64) base.status {
    if this.call_sequence < 0x20 {
        return base."#bad call sequence"
    }
    if args.index <> 0 {
        // In terms of the file format, NIA animation timings are absolute (the
        // time since the start of the animation) instead of relative (the time
        // since the previous frame), to allow for seek-to-timestamp via binary
        // search. But Wuffs' decode_frame_config API returns relative frame
        // durations. When decoding NIA frames, this is easy to provide for
        // sequential access but a little trickier for random access.
        //
        // For now, we only allow restart_frame with an args.index of 0. If
        // users really want random access restarts, we could seek to frame
        // (args.index - 1) and calculate the relative frame duration. But
        // until users ask for it, we won't implement that complexity.
        return "#unsupported restart frame index"
    } else if args.io_position <> 16 {
        return base."#bad argument"
    }
    this.num_animation_loops_value = 0
    this.prev_duration = 0
    this.curr_duration = 0
    this.num_decoded_frame_configs_value = 0
    this.num_decoded_frames_value = 0
    this.call_sequence = 0x28
    return ok
}

pub func decoder.set_report_metadata!(fourcc: base.u32, report: base.bool) {
    // No-op. NIE doesn't support metadata.
}

pub func decoder.tell_me_more?(dst: base.io_writer, minfo: nptr base.more_information, src: base.io_reader) {
    return base."#no more information"
}

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