/*
 * au_auth_dbio.pgc - 승인(authorization)/부정거래 DB 접근 (libaudbio.a).
 * ECPG functions; run on the caller's XA branch. No EXEC SQL CONNECT.
 */
#include <string.h>
#include <userlog.h>
#include "au_dbio.h"

long audb_next_auth_id(void)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id;
    EXEC SQL END DECLARE SECTION;

    EXEC SQL SELECT nextval('au_auth_seq') INTO :h_id;
    if (sqlca.sqlcode < 0) {
        userlog("audb_next_auth_id FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return h_id;
}

int audb_insert_auth(long auth_id, const char *card, const char *merch, long amount,
                     const char *appr_code, const char *auth_type, const char *status,
                     const char *bizdate)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id = auth_id, h_amount = amount;
    char h_card[24], h_merch[64], h_appr[12], h_type[12], h_status[8], h_bizdate[16];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1);       h_card[sizeof(h_card)-1] = 0;
    strncpy(h_merch, merch, sizeof(h_merch) - 1);    h_merch[sizeof(h_merch)-1] = 0;
    strncpy(h_appr, appr_code, sizeof(h_appr) - 1);  h_appr[sizeof(h_appr)-1] = 0;
    strncpy(h_type, auth_type, sizeof(h_type) - 1);  h_type[sizeof(h_type)-1] = 0;
    strncpy(h_status, status, sizeof(h_status) - 1); h_status[sizeof(h_status)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL INSERT INTO au_authorization
        (auth_id, card_no, merchant_id, amount, approval_code, auth_type, status, biz_date)
        VALUES (:h_id, :h_card, :h_merch, :h_amount, :h_appr, :h_type, :h_status, :h_bizdate);
    if (sqlca.sqlcode < 0) {
        userlog("audb_insert_auth FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int audb_update_auth_status(long auth_id, const char *status)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id = auth_id;
    char h_status[8];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_status, status, sizeof(h_status) - 1); h_status[sizeof(h_status)-1] = 0;

    EXEC SQL UPDATE au_authorization SET status = :h_status, updated_at = now()
        WHERE auth_id = :h_id;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_update_auth_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

int audb_get_auth_status(long auth_id, char *out)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id = auth_id;
    char h_status[8];
    EXEC SQL END DECLARE SECTION;

    EXEC SQL SELECT status INTO :h_status FROM au_authorization WHERE auth_id = :h_id;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_get_auth_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    out[0] = h_status[0];
    out[1] = 0;
    return 0;
}

int audb_update_auth_amount(long auth_id, long amount)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id = auth_id, h_amount = amount;
    EXEC SQL END DECLARE SECTION;

    EXEC SQL UPDATE au_authorization SET amount = :h_amount, updated_at = now()
        WHERE auth_id = :h_id;
    if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
        userlog("audb_update_auth_amount FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return 0;
}

long audb_insert_fraud(long auth_id, const char *card, long score, const char *reason,
                       const char *bizdate)
{
    EXEC SQL BEGIN DECLARE SECTION;
    long h_id, h_auth = auth_id, h_score = score;
    char h_card[24], h_reason[128], h_bizdate[16];
    EXEC SQL END DECLARE SECTION;

    strncpy(h_card, card, sizeof(h_card) - 1);       h_card[sizeof(h_card)-1] = 0;
    strncpy(h_reason, reason, sizeof(h_reason) - 1); h_reason[sizeof(h_reason)-1] = 0;
    strncpy(h_bizdate, bizdate, sizeof(h_bizdate) - 1); h_bizdate[sizeof(h_bizdate)-1] = 0;

    EXEC SQL SELECT nextval('au_fraud_seq') INTO :h_id;
    if (sqlca.sqlcode < 0) return -1;

    EXEC SQL INSERT INTO au_fraud_log (fraud_id, auth_id, card_no, score, reason, biz_date)
        VALUES (:h_id, :h_auth, :h_card, :h_score, :h_reason, :h_bizdate);
    if (sqlca.sqlcode < 0) {
        userlog("audb_insert_fraud FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }
    return h_id;
}
