/* @tier easy @module cl @transform closing-online */
/*
 * cl_ol_0026.pgc - 마감 온라인 서비스 (CL_OL_0026)  [tier=easy]
 *
 * 미마감 목록: 요청 영업일(BIZDATE)에서 미마감(R)/불일치(U) 상태의
 * 원장을 커서(cur_cl_ol_0026)로 순회하여 상위 N건의 처리키를 응답
 * 필드(KEY1..KEYN)로 나열하고, 총 미마감 대상 건수를 함께 반환한다.
 * N(LIMIT)은 입력으로 받되 1..20 범위로 보정한다.
 */
#include <stdio.h>
#include <string.h>

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

EXEC SQL INCLUDE sqlca;

#define CL_OL_0026_MAX 20

TX_SERVICE(CL_OL_0026, ctx)
{
    EXEC SQL BEGIN DECLARE SECTION;
    char h_biz_date[9];
    char h_key[16];
    int  h_total;
    EXEC SQL END DECLARE SECTION;

    char bizdate[16];
    char fld[16];
    long limit = 0;
    int  listed = 0;
    int  cur_open = 0;

    tx_log(TX_LOG_INFO, "[CL_OL_0026] 미마감 목록 서비스 진입");

    /* 1) 입력 수신 및 검증 */
    if (tx_buf_get(ctx->in, "BIZDATE", bizdate, sizeof(bizdate)) != TX_OK) {
        tx_log(TX_LOG_ERROR, "[CL_OL_0026] BIZDATE 누락");
        tx_buf_reset(ctx->out);
        tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID);
        tx_return(ctx, TX_EINVAL, ctx->out);
        return;
    }
    if (!date_is_valid(bizdate)) {
        tx_log(TX_LOG_WARN, "[CL_OL_0026] 영업일 형식 오류 date=%s", bizdate);
        tx_buf_reset(ctx->out);
        tx_buf_sets(ctx->out, "RESPCODE", RESP_INVALID);
        tx_return(ctx, TX_EINVAL, ctx->out);
        return;
    }

    /* LIMIT 보정 (1..MAX) */
    tx_buf_getlong(ctx->in, "LIMIT", &limit);
    if (limit <= 0)
        limit = 10;
    if (limit > CL_OL_0026_MAX)
        limit = CL_OL_0026_MAX;

    memset(h_biz_date, 0, sizeof(h_biz_date));
    strncpy(h_biz_date, bizdate, sizeof(h_biz_date) - 1);

    /* 2) 총 미마감(R,U) 건수 */
    EXEC SQL SELECT count(*)
        INTO :h_total
        FROM cl_ledger
        WHERE biz_date = :h_biz_date
          AND status IN ('R', 'U');

    if (sqlca.sqlcode != TX_SQL_OK) {
        TX_DBIO_LOG_ERR("cl_ol_0026 총건수");
        tx_buf_reset(ctx->out);
        tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
        tx_return(ctx, TX_EDB, ctx->out);
        return;
    }

    tx_buf_reset(ctx->out);

    /* 3) 커서로 상위 N건 처리키 나열 */
    EXEC SQL DECLARE cur_cl_ol_0026 CURSOR FOR
        SELECT key
        FROM cl_ledger
        WHERE biz_date = :h_biz_date
          AND status IN ('R', 'U')
        ORDER BY key;

    EXEC SQL OPEN cur_cl_ol_0026;
    if (sqlca.sqlcode != TX_SQL_OK) {
        TX_DBIO_LOG_ERR("cl_ol_0026 OPEN");
        tx_buf_sets(ctx->out, "RESPCODE", RESP_SYSERR);
        tx_return(ctx, TX_EDB, ctx->out);
        return;
    }
    cur_open = 1;

    while (listed < (int)limit) {
        EXEC SQL FETCH cur_cl_ol_0026 INTO :h_key;
        if (sqlca.sqlcode == TX_SQL_NOTFOUND)
            break;
        if (sqlca.sqlcode != TX_SQL_OK) {
            TX_DBIO_LOG_ERR("cl_ol_0026 FETCH");
            break;
        }
        listed++;
        snprintf(fld, sizeof(fld), "KEY%d", listed);
        tx_buf_sets(ctx->out, fld, h_key);
    }

    if (cur_open)
        EXEC SQL CLOSE cur_cl_ol_0026;

    /* 4) 응답 요약 */
    tx_buf_sets(ctx->out, "RESPCODE", RESP_OK);
    tx_buf_sets(ctx->out, "BIZDATE", bizdate);
    tx_buf_setlong(ctx->out, "TOTALCNT", (long)h_total);
    tx_buf_setlong(ctx->out, "LISTED", (long)listed);

    tx_log(TX_LOG_INFO, "[CL_OL_0026] 완료 date=%s 총미마감=%d 목록=%d",
           bizdate, h_total, listed);
    tx_return(ctx, TX_OK, ctx->out);
}
