/* @tier medium @module cm @transform common-online */
/*
 * cm_ol_0020.pgc - 금액 한글 표기 서비스 (CM_OL_0020)  [tier=medium]
 *
 * 요청의 금액(AMOUNT)을 만/억/조 단위 절(節)로 분해하여 한글 금액표기
 * (예: 123000000 -> "일억이천삼백만")로 변환하여 응답한다. 증서/전표
 * 출력용 변환 서비스. 변환 결과는 증서 발급 감사이력(cm_amt_hangeul_log)
 * 에 적재하여 발급 근거로 남긴다. (ATMI void SVC(TPSVCINFO*) 대응)
 */
#include <stdio.h>
#include <string.h>

#include "txcore.h"
#include "txcore_dbio.h"
#include "acq_util.h"
#include "cm_core.h"

EXEC SQL INCLUDE sqlca;

/* 0~9999 한 절(節)을 천/백/십 단위 한글로 변환하여 out 에 누적 */
static void hangeul_group(int val, char *out, int outlen)
{
    static const char *DIG[10] = {
        "", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구"
    };
    static const char *POS[4] = { "", "십", "백", "천" };
    int unit[4];
    int i;

    unit[3] = (val / 1000) % 10;
    unit[2] = (val / 100)  % 10;
    unit[1] = (val / 10)   % 10;
    unit[0] =  val         % 10;

    for (i = 3; i >= 0; i--) {
        if (unit[i] == 0)
            continue;
        /* 십/백/천 자리의 '일'은 관용상 생략 (예: 15 -> 십오) */
        if (!(unit[i] == 1 && i > 0))
            strncat(out, DIG[unit[i]], outlen - strlen(out) - 1);
        strncat(out, POS[i], outlen - strlen(out) - 1);
    }
}

TX_SERVICE(CM_OL_0020, ctx)
{
    static const char *GUNIT[4] = { "", "만", "억", "조" };

    EXEC SQL BEGIN DECLARE SECTION;
    long h_amount;
    char h_hangeul[128];
    EXEC SQL END DECLARE SECTION;

    char hangeul[128];
    char won_fmt[48];
    long amount = 0;
    long n;
    long logged = 0;
    int  neg = 0;
    int  groups[4];
    int  i;

    tx_log(TX_LOG_INFO, "[CM_OL_0020] 금액 한글 표기 서비스 진입");

    if (tx_buf_getlong(ctx->in, "AMOUNT", &amount) != TX_OK) {
        tx_log(TX_LOG_ERROR, "[CM_OL_0020] AMOUNT 누락");
        tx_return(ctx, TX_EINVAL, ctx->out);
        return;
    }

    hangeul[0] = '\0';
    n = amount;
    if (n < 0) { neg = 1; n = -n; }

    if (n == 0) {
        strncpy(hangeul, "영", sizeof(hangeul) - 1);
    } else {
        /* 4자리 절 단위 분해: 일/만/억/조 (조 단위까지 지원) */
        for (i = 0; i < 4; i++) {
            groups[i] = (int)(n % 10000);
            n /= 10000;
        }
        for (i = 3; i >= 0; i--) {
            if (groups[i] == 0)
                continue;
            hangeul_group(groups[i], hangeul, sizeof(hangeul));
            strncat(hangeul, GUNIT[i], sizeof(hangeul) - strlen(hangeul) - 1);
        }
    }
    strncat(hangeul, "원", sizeof(hangeul) - strlen(hangeul) - 1);

    if (neg) {
        char tmp[128];
        snprintf(tmp, sizeof(tmp), "마이너스%s", hangeul);
        strncpy(hangeul, tmp, sizeof(hangeul) - 1);
        hangeul[sizeof(hangeul) - 1] = '\0';
    }

    /* 교차표시용: 콤마 구분 숫자표기 */
    amount_format_won(amount, won_fmt, sizeof(won_fmt));

    /* 변환 결과 증서 감사이력 적재 */
    h_amount = amount;
    strncpy(h_hangeul, hangeul, sizeof(h_hangeul) - 1);
    h_hangeul[sizeof(h_hangeul) - 1] = '\0';

    if (tx_begin() != TX_OK) {
        tx_log(TX_LOG_WARN, "[CM_OL_0020] tx_begin 경고");
    } else {
        EXEC SQL INSERT INTO cm_amt_hangeul_log
                (amount, hangeul_txt, conv_ts)
            VALUES (:h_amount, :h_hangeul, now());

        if (sqlca.sqlcode != TX_SQL_OK) {
            TX_DBIO_LOG_ERR("CM_OL_0020 INSERT cm_amt_hangeul_log");
            tx_abort();
        } else {
            logged = (long)sqlca.sqlerrd[2];
            tx_commit();
        }
    }

    tx_buf_reset(ctx->out);
    tx_buf_setlong(ctx->out, "AMOUNT", amount);
    tx_buf_sets(ctx->out, "HANGEUL", hangeul);
    tx_buf_sets(ctx->out, "WON", won_fmt);
    tx_buf_setlong(ctx->out, "LOGGED", logged);
    tx_log(TX_LOG_INFO, "[CM_OL_0020] 변환완료 amount=%ld -> %s", amount, hangeul);
    tx_return(ctx, TX_OK, ctx->out);
}
