/*
 * au_limit_restore_batch.pgc - au 임시한도 일괄 복원 배치 (커서 + UPDATE, XA).
 *
 * LIMIT_TEMP 로 임시 상향된 채 남아 있는 카드(temp_limit > 0)를 커서로 훑어
 * 카드마다 daily_limit 에서 임시분을 걷어내고 temp_limit 를 0 으로 되돌린다.
 * 전체가 ONE global XA transaction; 실패 시 tpabort 로 전량 원복.
 * Usage: au_limit_restore_batch
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "au_limit_restore_batch.h"

void aub_limit_restore_summary(const au_limit_restore_ctx_t *ctx, char *out, int cap)
{
    snprintf(out, cap, "cards=%ld amount=%ld", ctx->restored_cards, ctx->restored_amount);
}

int main(int argc, char **argv)
{
    au_limit_restore_ctx_t ctx;
    char line[80];

    EXEC SQL BEGIN DECLARE SECTION;
    char h_card[24];
    long h_temp;
    EXEC SQL END DECLARE SECTION;

    memset(&ctx, 0, sizeof(ctx));

    if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
    if (tpopen() < 0)     { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
    if (tpbegin(120, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }

    EXEC SQL DECLARE clrb CURSOR FOR
        SELECT card_no, temp_limit FROM card_limit
        WHERE temp_limit > 0 ORDER BY card_no;
    EXEC SQL OPEN clrb;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }

    for (;;) {
        EXEC SQL FETCH clrb INTO :h_card, :h_temp;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE clrb; tpabort(0); return 1; }
        EXEC SQL UPDATE card_limit
            SET daily_limit = daily_limit - :h_temp, temp_limit = 0, updated_at = now()
            WHERE card_no = :h_card AND temp_limit = :h_temp;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE clrb; tpabort(0); return 1; }
        ctx.restored_cards++;
        ctx.restored_amount += h_temp;
    }
    EXEC SQL CLOSE clrb;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    aub_limit_restore_summary(&ctx, line, sizeof(line));
    printf(">>> au_limit_restore_batch COMMIT: 임시한도 복원 %s\n", line);

    tpclose(); tpterm();
    return 0;
}
