/*
 * mm_rate_expire_batch.pgc - 장기 미결 요율 요청 자동 반려 배치 (커서 + XA).
 *
 * 접수 후 N일이 지나도록 승인/반려로 종결되지 않은 RATE_REQ를 자동 RATE_REJ 처리한다.
 * (SLA 초과 요청 정리). ONE global XA transaction.
 * host 변수는 mm_rate_expire_cpy.h 를 EXEC SQL INCLUDE.
 * Usage: mm_rate_expire_batch [DAYS=14]
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "mm_dbio.h"

int main(int argc, char **argv)
{
    EXEC SQL INCLUDE mm_rate_expire_cpy;
    b_rejected = 0;
    b_days = (argc > 1) ? atol(argv[1]) : 14;
    if (b_days < 1) b_days = 14;

    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(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }

    EXEC SQL DECLARE rex CURSOR FOR
        SELECT DISTINCT r.merchant_id
        FROM mm_merch_hist r
        WHERE r.action = 'RATE_REQ'
          AND r.created_at < now() - (:b_days || ' days')::interval
          AND NOT EXISTS (SELECT 1 FROM mm_merch_hist d
                          WHERE d.merchant_id = r.merchant_id
                            AND d.action IN ('RATE_APV', 'RATE_REJ') AND d.hist_id > r.hist_id)
        ORDER BY r.merchant_id;
    EXEC SQL OPEN rex;
    if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }

    for (;;) {
        EXEC SQL FETCH rex INTO :b_merch;
        if (sqlca.sqlcode == 100) break;
        if (sqlca.sqlcode < 0) { EXEC SQL CLOSE rex; tpabort(0); return 1; }
        if (mmdb_insert_merch_hist(b_merch, "RATE_REJ", "PENDING", "EXPIRED", "SLA 초과 자동 반려") < 0) {
            EXEC SQL CLOSE rex; tpabort(0); return 1;
        }
        b_rejected++;
    }
    EXEC SQL CLOSE rex;

    if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
    printf(">>> mm_rate_expire_batch COMMIT: 기준=%ld일 자동반려=%ld건\n", b_days, b_rejected);

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