/*
 * The deflate_quick deflate strategy, designed to be used when cycles are
 * at a premium.
 *
 * Copyright (C) 2013 Intel Corporation. All rights reserved.
 * Authors:
 *  Wajdi Feghali   <wajdi.k.feghali@intel.com>
 *  Jim Guilford    <james.guilford@intel.com>
 *  Vinodh Gopal    <vinodh.gopal@intel.com>
 *     Erdinc Ozturk   <erdinc.ozturk@intel.com>
 *  Jim Kukunas     <james.t.kukunas@linux.intel.com>
 *
 * Portions are Copyright (C) 2016 12Sided Technology, LLC.
 * Author:
 *  Phil Vachon     <pvachon@12sidedtech.com>
 *
 * For conditions of distribution and use, see copyright notice in zlib.h
 */

#include "zbuild.h"
#include "zutil_p.h"
#include "deflate.h"
#include "deflate_p.h"
#include "functable.h"
#include "trees_emit.h"

extern const ct_data static_ltree[L_CODES+2];
extern const ct_data static_dtree[D_CODES];

#define QUICK_START_BLOCK(s, last) { \
    zng_tr_emit_tree(s, STATIC_TREES, last); \
    s->block_open = 1 + (int)last; \
    s->block_start = (int)s->strstart; \
}

#define QUICK_END_BLOCK(s, last) { \
    if (s->block_open) { \
        zng_tr_emit_end_block(s, static_ltree, last); \
        s->block_open = 0; \
        s->block_start = (int)s->strstart; \
        PREFIX(flush_pending)(s->strm); \
        if (s->strm->avail_out == 0) \
            return (last) ? finish_started : need_more; \
    } \
}

Z_INTERNAL block_state deflate_quick(deflate_state *s, int flush) {
    Pos hash_head;
    int64_t dist;
    unsigned match_len, last;


    last = (flush == Z_FINISH) ? 1 : 0;
    if (UNLIKELY(last && s->block_open != 2)) {
        /* Emit end of previous block */
        QUICK_END_BLOCK(s, 0);
        /* Emit start of last block */
        QUICK_START_BLOCK(s, last);
    } else if (UNLIKELY(s->block_open == 0 && s->lookahead > 0)) {
        /* Start new block only when we have lookahead data, so that if no
           input data is given an empty block will not be written */
        QUICK_START_BLOCK(s, last);
    }

    for (;;) {
        if (UNLIKELY(s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size)) {
            PREFIX(flush_pending)(s->strm);
            if (s->strm->avail_out == 0) {
                return (last && s->strm->avail_in == 0 && s->bi_valid == 0 && s->block_open == 0) ? finish_started : need_more;
            }
        }

        if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD)) {
            PREFIX(fill_window)(s);
            if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) {
                return need_more;
            }
            if (UNLIKELY(s->lookahead == 0))
                break;

            if (UNLIKELY(s->block_open == 0)) {
                /* Start new block when we have lookahead data, so that if no
                   input data is given an empty block will not be written */
                QUICK_START_BLOCK(s, last);
            }
        }

        if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) {
            hash_head = functable.quick_insert_string(s, s->strstart);
            dist = (int64_t)s->strstart - hash_head;

            if (dist <= MAX_DIST(s) && dist > 0) {
                const uint8_t *str_start = s->window + s->strstart;
                const uint8_t *match_start = s->window + hash_head;

                if (zng_memcmp_2(str_start, match_start) == 0) {
                    match_len = functable.compare256(str_start+2, match_start+2) + 2;

                    if (match_len >= WANT_MIN_MATCH) {
                        if (UNLIKELY(match_len > s->lookahead))
                            match_len = s->lookahead;
                        if (UNLIKELY(match_len > STD_MAX_MATCH))
                            match_len = STD_MAX_MATCH;

                        check_match(s, s->strstart, hash_head, match_len);

                        zng_tr_emit_dist(s, static_ltree, static_dtree, match_len - STD_MIN_MATCH, (uint32_t)dist);
                        s->lookahead -= match_len;
                        s->strstart += match_len;
                        continue;
                    }
                }
            }
        }

        zng_tr_emit_lit(s, static_ltree, s->window[s->strstart]);
        s->strstart++;
        s->lookahead--;
    }

    s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1);
    if (UNLIKELY(last)) {
        QUICK_END_BLOCK(s, 1);
        return finish_done;
    }

    QUICK_END_BLOCK(s, 0);
    return block_done;
}
