/*
 * 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_CHOICE.h>
#include <errno.h>

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

#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
#define NEXT_PHASE(ctx) \
    do {                \
        ctx->phase++;   \
        ctx->step = 0;  \
    } while(0)
#undef  SET_PHASE
#define SET_PHASE(ctx, value) \
    do {                      \
        ctx->phase = value;   \
        ctx->step = 0;        \
    } while(0)

/*
 * Tags are canonically sorted in the tag to member table.
 */
static int
_search4tag(const void *ap, const void *bp) {
    const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
    const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;

    int a_class = BER_TAG_CLASS(a->el_tag);
    int b_class = BER_TAG_CLASS(b->el_tag);

    if(a_class == b_class) {
        ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
        ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);

        if(a_value == b_value)
            return 0;
        else if(a_value < b_value)
            return -1;
        else
            return 1;
    } else if(a_class < b_class) {
        return -1;
    } else {
        return 1;
    }
}

/*
 * X.696 (08/2015) #8.7 Encoding of tags
 */
static ssize_t
oer_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) {
    ber_tlv_tag_t val;
    ber_tlv_tag_t tclass;
    size_t skipped;

    if(size == 0)
        return 0;

    val = *(const uint8_t *)ptr;
    tclass = (val >> 6);
    if((val & 0x3F) != 0x3F) {
        /* #8.7.1 */
        *tag_r = ((val & 0x3F) << 2) | tclass;
        return 1;
    }

    /*
     * Each octet contains 7 bits of useful information.
     * The MSB is 0 if it is the last octet of the tag.
     */
    for(val = 0, ptr = ((const char *)ptr) + 1, skipped = 2; skipped <= size;
        ptr = ((const char *)ptr) + 1, skipped++) {
        unsigned int oct = *(const uint8_t *)ptr;
        if(oct & 0x80) {
            val = (val << 7) | (oct & 0x7F);
            /*
             * Make sure there are at least 9 bits spare
             * at the MS side of a value.
             */
            if(val >> ((8 * sizeof(val)) - 9)) {
                /*
                 * We would not be able to accomodate
                 * any more tag bits.
                 */
                return -1;
            }
        } else {
            val = (val << 7) | oct;
            *tag_r = (val << 2) | tclass;
            return skipped;
        }
    }

    return 0; /* Want more */
}

asn_dec_rval_t
CHOICE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
                  const asn_oer_constraints_t *constraints, void **struct_ptr,
                  const void *ptr, size_t size) {
    /*
     * Bring closer parts of structure description.
     */
    asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
    asn_TYPE_member_t *elements = td->elements;

    /*
     * Parts of the structure being constructed.
     */
    void *st = *struct_ptr; /* Target structure. */
    asn_struct_ctx_t *ctx;  /* Decoder context */

    ssize_t consumed_myself = 0; /* Consumed bytes from ptr */

    (void)constraints;

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

    /*
     * 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);
    switch(ctx->phase) {
    case 0: {
        /*
         * Discover the tag.
         */
        ber_tlv_tag_t tlv_tag; /* T from TLV */
        ssize_t tag_len;       /* Length of TLV's T */

        tag_len = oer_fetch_tag(ptr, size, &tlv_tag);
        switch(tag_len) {
        case 0:
            ASN__DECODE_STARVED;
        case -1:
            ASN__DECODE_FAILED;
        }

        do {
            const asn_TYPE_tag2member_t *t2m;
            asn_TYPE_tag2member_t key = {0, 0, 0, 0};
            key.el_tag = tlv_tag;

            t2m = (const asn_TYPE_tag2member_t *)bsearch(
                &key, specs->tag2el, specs->tag2el_count,
                sizeof(specs->tag2el[0]), _search4tag);
            if(t2m) {
                /*
                 * Found the element corresponding to the tag.
                 */
                NEXT_PHASE(ctx);
                ctx->step = t2m->el_no;
                break;
            } else if(specs->ext_start == -1) {
                ASN_DEBUG(
                    "Unexpected tag %s "
                    "in non-extensible CHOICE %s",
                    ber_tlv_tag_string(tlv_tag), td->name);
                RETURN(RC_FAIL);
            } else {
                /* Skip open type extension */
                ASN_DEBUG(
                    "Not implemented skipping open type extension for tag %s",
                    ber_tlv_tag_string(tlv_tag));
                RETURN(RC_FAIL);
            }
        } while(0);


        ADVANCE(tag_len);
    }
        /* Fall through */
    case 1: {
        asn_TYPE_member_t *elm = &elements[ctx->step]; /* CHOICE's element */
        void *memb_ptr;         /* Pointer to the member */
        void **memb_ptr2;       /* Pointer to that pointer */
        asn_dec_rval_t rval;

        /*
         * Compute the position of the member inside a structure,
         * and also a type of containment (it may be contained
         * as pointer or using inline inclusion).
         */
        if(elm->flags & ATF_POINTER) {
            /* Member is a pointer to another structure */
            memb_ptr2 = (void **)((char *)st + elm->memb_offset);
        } else {
            /*
             * A pointer to a pointer
             * holding the start of the structure
             */
            memb_ptr = (char *)st + elm->memb_offset;
            memb_ptr2 = &memb_ptr;
        }

        /* Set presence to be able to free it properly at any time */
        (void)CHOICE_variant_set_presence(td, st, ctx->step + 1);

        if(specs->ext_start >= 0 && specs->ext_start <= ctx->step) {
            /* We're in the extensions group. #20.2 requires Open Type */
            ASN_DEBUG("Not implemented %s es=%d, edx=%u at %s:%d", td->name,
                      specs->ext_start, ctx->step, __FILE__, __LINE__);
            RETURN(RC_FAIL);
        }

        rval = elm->type->op->oer_decoder(opt_codec_ctx, elm->type,
                                          elm->oer_constraints, memb_ptr2, ptr,
                                          size);
        rval.consumed += consumed_myself;
        switch(rval.code) {
        case RC_OK:
            NEXT_PHASE(ctx);
        case RC_WMORE:
            break;
        case RC_FAIL:
            SET_PHASE(ctx, 3);  /* => 3 */
        }
        return rval;
    }
    case 2:
        /* Already decoded everything */
        RETURN(RC_OK);
    case 3:
        /* Failed to decode, after all */
        RETURN(RC_FAIL);
    }

    RETURN(RC_FAIL);
}

/*
 * X.696 (08/2015) #8.7 Encoding of tags
 */
static ssize_t
oer_put_tag(ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
    uint8_t tclass = BER_TAG_CLASS(tag);
    ber_tlv_tag_t tval = BER_TAG_VALUE(tag);

    if(tval < 0x3F) {
        uint8_t b = (uint8_t)((tclass << 6) | tval);
        if(cb(&b, 1, app_key) < 0) {
            return -1;
        }
        return 1;
    } else {
        uint8_t buf[1 + 2 * sizeof(tval)];
        uint8_t *b = &buf[sizeof(buf)-1]; /* Last addressable */
        size_t encoded;
        for(; ; tval >>= 7) {
            if(tval >> 7) {
                *b-- = 0x80 | (tval & 0x7f);
            } else {
                *b-- = tval & 0x7f;
                break;
            }
        }
        *b = (uint8_t)((tclass << 6) | 0x3F);
        encoded = sizeof(buf) - (b - buf);
        if(cb(b, encoded, app_key) < 0) {
            return -1;
        }
        return encoded;
    }

}

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
CHOICE_encode_oer(asn_TYPE_descriptor_t *td,
                  const asn_oer_constraints_t *constraints, void *sptr,
                  asn_app_consume_bytes_f *cb, void *app_key) {
    asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
    asn_TYPE_member_t *elm; /* CHOICE element */
    unsigned present;
    void *memb_ptr;
    ber_tlv_tag_t tag;
    ssize_t tag_len;
    asn_enc_rval_t er;

    (void)constraints;
    (void)specs;

    if(!sptr) ASN__ENCODE_FAILED;

    ASN_DEBUG("OER %s encoding as CHOICE", td->name);

    present = CHOICE_variant_get_presence(td, sptr);
    if(present == 0 || present > td->elements_count) {
        ASN_DEBUG("CHOICE %s member is not selected", td->name);
        ASN__ENCODE_FAILED;
    }

    elm = &td->elements[present-1];
    if(elm->flags & ATF_POINTER) {
        memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
        if(memb_ptr == 0) {
            /* Mandatory element absent */
            ASN__ENCODE_FAILED;
        }
    } else {
        memb_ptr = (void *)((char *)sptr + elm->memb_offset);
    }

    tag = asn_TYPE_outmost_tag(elm->type, memb_ptr, elm->tag_mode, elm->tag);
    if(tag == 0) {
        ASN__ENCODE_FAILED;
    }

    tag_len = oer_put_tag(tag, cb, app_key);
    if(tag_len < 0) {
        ASN__ENCODE_FAILED;
    }

    er = elm->type->op->oer_encoder(elm->type, elm->oer_constraints, memb_ptr,
                                    cb, app_key);
    if(er.encoded > 0)
        er.encoded += tag_len;

    return er;
}

#endif  /* ASN_DISABLE_OER_SUPPORT */
