/*
 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
 * All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#ifndef ASN_DISABLE_OER_SUPPORT

#include <asn_internal.h>
#include <constr_SEQUENCE.h>
#include <OPEN_TYPE.h>
#include <errno.h>

/*
 * This macro "eats" the part of the buffer which is definitely "consumed",
 * i.e. was correctly converted into local representation or rightfully skipped.
 */
#undef  ADVANCE
#define ADVANCE(num_bytes)                   \
    do {                                     \
        size_t num = num_bytes;              \
        ptr = ((const char *)ptr) + num;     \
        size -= num;                         \
        consumed_myself += num;              \
    } while(0)

/*
 * Switch to the next phase of parsing.
 */
#undef  NEXT_PHASE
#undef PHASE_OUT
#define NEXT_PHASE(ctx) \
    do {                \
        ctx->phase++;   \
        ctx->step = 0;  \
    } while(0)

/*
 * Check whether we are inside the extensions group.
 */
#define IN_EXTENSION_GROUP(specs, memb_idx)     \
        ( (((ssize_t)(memb_idx)) > (specs)->ext_after)     \
        &&(((ssize_t)(memb_idx)) < (specs)->ext_before))

/*
 * Return a standardized complex structure.
 */
#undef  RETURN
#define RETURN(_code)   do {                    \
                rval.code = _code;              \
                rval.consumed = consumed_myself;\
                return rval;                    \
        } while(0)

/*
 * Return pointer to a member.
 */
static void **
element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
    if(elm->flags & ATF_POINTER) {
        /* Member is a pointer to another structure */
        return (void **)((char *)struct_ptr + elm->memb_offset);
    } else {
        assert(tmp_save_ptr);
        *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
        return tmp_save_ptr;
    }
}

static const void *
element_ptr(const void *struct_ptr, const asn_TYPE_member_t *elm) {
    if(elm->flags & ATF_POINTER) {
        /* Member is a pointer to another structure */
        return *(const void *const *)((const char *)struct_ptr
                                      + elm->memb_offset);
    } else {
        return (const void *)((const char *)struct_ptr + elm->memb_offset);
    }
}

asn_dec_rval_t
SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
                    const asn_TYPE_descriptor_t *td,
                    const asn_oer_constraints_t *constraints, void **struct_ptr,
                    const void *ptr, size_t size) {
    const asn_SEQUENCE_specifics_t *specs =
        (const asn_SEQUENCE_specifics_t *)td->specifics;
    asn_dec_rval_t rval = {RC_OK, 0};
    void *st = *struct_ptr; /* Target structure */
    asn_struct_ctx_t *ctx; /* Decoder context */
    size_t consumed_myself = 0; /* Consumed bytes from ptr. */


    (void)opt_codec_ctx;
    (void)constraints;

    /*
     * Create the target structure if it is not present already.
     */
    if(st == 0) {
        st = *struct_ptr = CALLOC(1, specs->struct_size);
        if(st == 0) {
            RETURN(RC_FAIL);
        }
    }

    /*
     * Restore parsing context.
     */
    ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
    if(ctx->ptr == 0) {
        ctx->ptr = CALLOC(1, sizeof(asn_bit_data_t));
        if(!ctx->ptr) {
            RETURN(RC_FAIL);
        }
    }

    /*
     * Start to parse where left previously.
     */
    switch(ctx->phase) {
    case 0: {
        /*
         * Fetch preamble.
         */
        asn_bit_data_t *preamble = ctx->ptr;
        int has_extensions_bit = (specs->ext_before >= 0);
        size_t preamble_bits = (has_extensions_bit + specs->roms_count);
        size_t preamble_bytes = ((7 + preamble_bits) >> 3);
        uint8_t *pbytes;

        ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 0", td->name);

        ASN_DEBUG(
            "Expecting preamble bits %zu for %s (including %d extension bits)",
            preamble_bits, td->name, has_extensions_bit);

        if(size < preamble_bytes) {
            ASN__DECODE_STARVED;
        }

        pbytes = MALLOC(preamble_bytes + 1);
        if(!pbytes) {
            RETURN(RC_FAIL);
        }
        preamble->buffer = (const void *)pbytes;
        memcpy(pbytes, ptr, preamble_bytes);
        pbytes[preamble_bytes] = '\0';    /* Just in case */
        preamble->nboff = has_extensions_bit;
        preamble->nbits = preamble_bits;
        ADVANCE(preamble_bytes);
    }
        NEXT_PHASE(ctx);
        /* FALL THROUGH */
    case 1: {
        /* Decode components of the extension root */
        asn_bit_data_t *preamble = ctx->ptr;
        size_t edx;

        ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1", td->name);

        for(edx = (ctx->step >> 1); edx < td->elements_count;
            edx++, ctx->step = (ctx->step & ~1) + 2) {
            asn_TYPE_member_t *elm = &td->elements[edx];

            ASN_DEBUG("Decoding %s->%s", td->name, elm->name);

            if(ctx->step & 1) {
                goto microphase2_decode_continues;
            }


            if(IN_EXTENSION_GROUP(specs, edx)) {
                /* Ignore non-root components in PHASE 1 */
                break;
            }

            if(elm->optional) {
                int32_t present = asn_get_few_bits(preamble, 1);
                if(present < 0) {
                    ASN_DEBUG("Presence map ended prematurely: %d", present);
                    RETURN(RC_FAIL);
                } else if(present == 0) {
                    if(elm->default_value_set) {
                        /* Fill-in DEFAULT */
                        void *tmp;
                        if(elm->default_value_set(
                               element_ptrptr(st, elm, &tmp))) {
                            RETURN(RC_FAIL);
                        }
                    }
                    /* The member is not present. */
                    continue;
                }
                /* Present OPTIONAL or DEFAULT component. */
            }

            /*
             * MICROPHASE 2: Invoke the member-specific decoder.
             */
            ctx->step |= 1; /* Confirm entering next microphase */
        microphase2_decode_continues:
            if(elm->flags & ATF_OPEN_TYPE) {
                rval = OPEN_TYPE_oer_get(opt_codec_ctx, td, st, elm, ptr, size);
            } else {
                void *save_memb_ptr; /* Temporary reference. */
                void **memb_ptr2;  /* Pointer to a pointer to a memmber */

                memb_ptr2 = element_ptrptr(st, elm, &save_memb_ptr);

                rval = elm->type->op->oer_decoder(opt_codec_ctx, elm->type,
                                                  elm->encoding_constraints.oer_constraints,
                                                  memb_ptr2, ptr, size);
            }
            switch(rval.code) {
            case RC_OK:
                ADVANCE(rval.consumed);
                break;
            case RC_WMORE:
                ASN_DEBUG("More bytes needed at element %s \"%s\"", td->name,
                          elm->name);
                ADVANCE(rval.consumed);
                RETURN(RC_WMORE);
            case RC_FAIL:
                ASN_DEBUG("Decoding failed at element %s \"%s\"", td->name,
                          elm->name);
                RETURN(RC_FAIL);
            }
        } /* for(all root members) */

    }
        NEXT_PHASE(ctx);
        /* FALL THROUGH */
    case 2: {
        /* Cleanup preamble. */
        asn_bit_data_t *preamble = ctx->ptr;
        asn_bit_data_t *extadds;
        int has_extensions_bit = (specs->ext_before >= 0);
        int extensions_present =
            has_extensions_bit
            && (preamble->buffer == NULL
                || (((const uint8_t *)preamble->buffer)[0] & 0x80));
        uint8_t unused_bits;
        size_t len = 0;
        ssize_t len_len;
        uint8_t *ebytes;

        union {
            const uint8_t *cptr;
            uint8_t *uptr;
        } unconst;

        ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 2", td->name);

        unconst.cptr = preamble->buffer;
        FREEMEM(unconst.uptr);
        preamble->buffer = 0; /* Will do extensions_present==1 next time. */

        if(!extensions_present) {
            ctx->phase = 10;
            RETURN(RC_OK);
        }

        /*
         * X.696 (08/2015) #16.1 (c), #16.4
         * Read in the extension addition presence bitmap.
         */

        len_len = oer_fetch_length(ptr, size, &len);
        if(len_len > 0) {
            ADVANCE(len_len);
        } if(len_len < 0) {
            RETURN(RC_FAIL);
        } else {
            RETURN(RC_WMORE);
        }

        if(len == 0) {
            /* 16.4.1-2 */
            RETURN(RC_FAIL);
        } else if(len > size) {
            RETURN(RC_WMORE);
        }

        /* Account for unused bits */
        unused_bits = 0x7 & *(const uint8_t *)ptr;
        ADVANCE(1);
        len--;
        if(unused_bits && len == 0) {
            RETURN(RC_FAIL);
        }

        /* Get the extensions map */
        ebytes = MALLOC(len + 1);
        if(!ebytes) {
            RETURN(RC_FAIL);
        }
        memcpy(ebytes, ptr, len);
        ebytes[len] = '\0';

        extadds = preamble;
        memset(extadds, 0, sizeof(*extadds));
        extadds->buffer = ebytes;
        extadds->nboff = 0;
        extadds->nbits = 8 * len - unused_bits;

        ADVANCE(len);
    }
        NEXT_PHASE(ctx);
        ctx->step = (specs->ext_after + 1);
        /* Fall through */
    case 3:
        ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3", td->name);
        for(; ctx->step < specs->ext_before - 1; ctx->step++) {
            asn_bit_data_t *extadds = ctx->ptr;
            size_t edx = ctx->step;
            asn_TYPE_member_t *elm = &td->elements[edx];
            void **memb_ptr2 = element_ptrptr(st, elm, 0);

            switch(asn_get_few_bits(extadds, 1)) {
            case -1:
                /*
                 * Not every one of our extensions is known to the remote side.
                 * Continue filling in their defaults though.
                 */
                /* Fall through */
            case 0:
                /* Fill-in DEFAULT */
                if(elm->default_value_set
                   && elm->default_value_set(memb_ptr2)) {
                    RETURN(RC_FAIL);
                }
                continue;
            case 1: {
                /* Read OER open type */
                ssize_t ot_size = oer_open_type_get(opt_codec_ctx, elm->type,
                                                    elm->encoding_constraints.oer_constraints,
                                                    memb_ptr2, ptr, size);
                if(ot_size > 0) {
                    ADVANCE(ot_size);
                } else if(ot_size < 0) {
                    RETURN(RC_FAIL);
                } else {
                    /* Roll back open type parsing */
                    asn_get_undo(extadds, 1);
                    ASN_STRUCT_FREE(*elm->type, *memb_ptr2);
                    *memb_ptr2 = NULL;
                    RETURN(RC_WMORE);
                }
                break;
            }
            default:
                RETURN(RC_FAIL);
            }
        }

        NEXT_PHASE(ctx);
        /* Fall through */
    case 4:
        ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 4", td->name);
        /* Read in the rest of Open Types while ignoring them */
        for(;;) {
            asn_bit_data_t *extadds = ctx->ptr;
            switch(asn_get_few_bits(extadds, 1)) {
            case 0:
                continue;
            case 1: {
                ssize_t skipped = oer_open_type_skip(ptr, size);
                if(skipped > 0) {
                    ADVANCE(skipped);
                } else if(skipped < 0) {
                    RETURN(RC_FAIL);
                } else {
                    asn_get_undo(extadds, 1);
                    RETURN(RC_WMORE);
                }
                continue;
            }
            case -1:
                /* No more Open Type encoded components */
                break;
            default:
                RETURN(RC_FAIL);
            }
            break;
        }
    }

    return rval;
}

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
                    const asn_oer_constraints_t *constraints, const void *sptr,
                    asn_app_consume_bytes_f *cb, void *app_key) {
    const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
    size_t computed_size = 0;
    int has_extensions_bit = (specs->ext_before >= 0);
    size_t preamble_bits = (has_extensions_bit + specs->roms_count);
    uint32_t has_extensions = 0;
    size_t edx;
    int ret;

    (void)constraints;

    if(preamble_bits) {
        asn_bit_outp_t preamble;

        memset(&preamble, 0, sizeof(preamble));
        preamble.output = cb;
        preamble.op_key = app_key;

        if(has_extensions_bit) {
            for(edx = specs->ext_after + 1;
                (ssize_t)edx < specs->ext_before - 1; edx++) {
                asn_TYPE_member_t *elm = &td->elements[edx];
                const void *memb_ptr = element_ptr(sptr, elm);
                if(memb_ptr) {
                    if(elm->default_value_cmp
                       && elm->default_value_cmp(memb_ptr) == 0) {
                        /* Do not encode default values in extensions */
                    } else {
                        has_extensions = 1;
                        break;
                    }
                }
            }
            ret = asn_put_few_bits(&preamble, has_extensions, 1);
            assert(ret == 0);
            if(ret < 0) {
                ASN__ENCODE_FAILED;
            }
        }

        /*
         * Encode optional components bitmap.
         */
        if(specs->roms_count) {
            for(edx = 0; edx < td->elements_count; edx++) {
                asn_TYPE_member_t *elm = &td->elements[edx];

                if(IN_EXTENSION_GROUP(specs, edx)) break;

                if(elm->optional) {
                    const void *memb_ptr = element_ptr(sptr, elm);
                    uint32_t has_component = memb_ptr != NULL;
                    if(has_component && elm->default_value_cmp
                       && elm->default_value_cmp(&memb_ptr) == 0) {
                        has_component = 0;
                    }
                    ret = asn_put_few_bits(&preamble, has_component, 1);
                    if(ret < 0) {
                        ASN__ENCODE_FAILED;
                    }
                }
            }
        }

        asn_put_aligned_flush(&preamble);
        computed_size += preamble.flushed_bytes;
    }   /* if(preamble_bits) */

    /*
     * Put root components and extensions root.
     */
    for(edx = 0; edx < td->elements_count; edx++) {
        asn_TYPE_member_t *elm = &td->elements[edx];
        asn_enc_rval_t er;
        const void *memb_ptr;

        if(IN_EXTENSION_GROUP(specs, edx)) break;

        memb_ptr = element_ptr(sptr, elm);
        if(memb_ptr) {
            if(elm->default_value_cmp
               && elm->default_value_cmp(memb_ptr) == 0) {
                /* Skip default values in encoding */
                continue;
            }
        } else {
            if(elm->optional) continue;
            /* Mandatory element is missing */
            ASN__ENCODE_FAILED;
        }
        if(!elm->type->op->oer_encoder) {
            ASN_DEBUG("OER encoder is not defined for type %s", elm->type->name);
            ASN__ENCODE_FAILED;
        }
        er = elm->type->op->oer_encoder(
            elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
            app_key);
        if(er.encoded == -1) {
            ASN_DEBUG("... while encoding %s member \"%s\"\n", td->name,
                      elm->name);
            return er;
        }
        computed_size += er.encoded;
    }

    /*
     * Before encode extensions, encode extensions additions presense bitmap
     # X.696 (08/2015) #16.4.
     */
    if(has_extensions) {
        asn_bit_outp_t extadds;

        /* Special case allowing us to use exactly one byte for #8.6 */
        size_t aoms_length_bits = specs->aoms_count;
        size_t aoms_length_bytes = (7 + aoms_length_bits) >> 3;
        uint8_t unused_bits = 0x07 & (8 - (aoms_length_bits & 0x07));

        assert(1 + aoms_length_bytes <= 127);

        memset(&extadds, 0, sizeof(extadds));
        extadds.output = cb;
        extadds.op_key = app_key;

        /* #8.6 length determinant */
        ret = asn_put_few_bits(&extadds, (1 + aoms_length_bytes), 8);
        if(ret < 0) ASN__ENCODE_FAILED;

        /* Number of unused bytes, #16.4.2 */
        ret = asn_put_few_bits(&extadds, unused_bits, 8);
        if(ret < 0) ASN__ENCODE_FAILED;

        /* Encode presence bitmap #16.4.3 */
        for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1;
            edx++) {
            asn_TYPE_member_t *elm = &td->elements[edx];
            const void *memb_ptr = element_ptr(sptr, elm);
            if(memb_ptr && elm->default_value_cmp
               && elm->default_value_cmp(memb_ptr) == 0) {
                memb_ptr = 0;   /* Do not encode default value. */
            }
            ret |= asn_put_few_bits(&extadds, memb_ptr ? 1 : 0, 1);
        }
        if(ret < 0) ASN__ENCODE_FAILED;

        asn_put_aligned_flush(&extadds);
        computed_size += extadds.flushed_bytes;

        /* Now, encode extensions */
        for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1;
            edx++) {
            asn_TYPE_member_t *elm = &td->elements[edx];
            const void *memb_ptr = element_ptr(sptr, elm);

            if(memb_ptr) {
                if(elm->default_value_cmp
                   && elm->default_value_cmp(memb_ptr) == 0) {
                    /* Do not encode default value. */
                } else {
                    asn_enc_rval_t er = elm->type->op->oer_encoder(
                        elm->type, elm->encoding_constraints.oer_constraints,
                        memb_ptr, cb, app_key);
                    if(er.encoded == -1) {
                        return er;
                    }
                    computed_size += er.encoded;
                }
            } else if(!elm->optional) {
                ASN__ENCODE_FAILED;
            }
        }
    }   /* if(has_extensions) */


    {
        asn_enc_rval_t er = {0, 0, 0};
        er.encoded = computed_size;
        ASN__ENCODED_OK(er);
    }
}

#endif  /* ASN_DISABLE_OER_SUPPORT */
