/* @tier medium @module mg @transform msg-gateway-online */
/*
 * mg_ol_0011.pgc - ISO8583식 필드 파싱 서비스 (MG_OL_0011)  [tier=medium]
 *
 * 요청의 primary bitmap(16 hex 문자 = 64bit)을 파싱하여 present 필드
 * 번호 목록을 추출하고, 비트온 개수/이차비트맵 사용여부를 응답한다.
 */
#include <stdio.h>
#include <string.h>

#include "txcore.h"
#include "acq_util.h"
#include "mg_core.h"

EXEC SQL INCLUDE sqlca;

TX_SERVICE(MG_OL_0011, ctx)
{
    char bitmap[24];
    char present[160];
    char hexbuf[8];
    int  i, nib, bit, fieldno, cnt = 0;
    int  secondary = 0;

    tx_log(TX_LOG_INFO, "[MG_OL_0011] ISO8583 비트맵 파싱 진입");

    if (tx_buf_get(ctx->in, "BITMAP", bitmap, sizeof(bitmap)) != TX_OK) {
        tx_log(TX_LOG_ERROR, "[MG_OL_0011] BITMAP 누락");
        tx_return(ctx, TX_EINVAL, ctx->out);
        return;
    }

    if (strlen(bitmap) < 16) {
        tx_log(TX_LOG_WARN, "[MG_OL_0011] 비트맵 길이부족 len=%d", (int)strlen(bitmap));
        tx_return(ctx, TX_EINVAL, ctx->out);
        return;
    }

    present[0] = '\0';

    /* 16 hex 문자 -> 64 bit, MSB = 필드1 */
    for (i = 0; i < 16; i++) {
        char c = bitmap[i];
        if (c >= '0' && c <= '9')      nib = c - '0';
        else if (c >= 'A' && c <= 'F') nib = c - 'A' + 10;
        else if (c >= 'a' && c <= 'f') nib = c - 'a' + 10;
        else {
            tx_log(TX_LOG_WARN, "[MG_OL_0011] 비16진 문자 pos=%d", i);
            tx_return(ctx, TX_EINVAL, ctx->out);
            return;
        }

        for (bit = 0; bit < 4; bit++) {
            if (nib & (1 << (3 - bit))) {
                fieldno = i * 4 + bit + 1;
                if (fieldno == 1)
                    secondary = 1;   /* 필드1 온 = secondary bitmap 존재 */
                snprintf(hexbuf, sizeof(hexbuf), "%d ", fieldno);
                if (strlen(present) + strlen(hexbuf) < sizeof(present))
                    strcat(present, hexbuf);
                cnt++;
            }
        }
    }

    tx_buf_reset(ctx->out);
    tx_buf_sets(ctx->out, "FIELDS", present);
    tx_buf_setlong(ctx->out, "COUNT", (long)cnt);
    tx_buf_setlong(ctx->out, "SECONDARY", (long)secondary);
    tx_log(TX_LOG_INFO, "[MG_OL_0011] 파싱완료 present=%d secondary=%d", cnt, secondary);
    tx_return(ctx, TX_OK, ctx->out);
}
