/*
 * mg_svr.pgc - mg (전문게이트웨이 / message gateway) MODULE SERVER (thin dispatcher).
 *
 * The legacy "one module server, many services" pattern: this binary owns NO
 * business logic. Each of mg's 133 online services now lives in its own file
 * (app/src/mg/svc/<SVCNAME>.pgc) with its own copybook header
 * (app/src/mg/svc/<SVCNAME>.h); those objects are archived into libmgsvc.a
 * and linked into this server. Here we only:
 *   - include every service copybook (for the extern prototypes),
 *   - tpopen() the ECPG XA RM,
 *   - tpadvertise() all 133 services from a {name, fn} table,
 *   - tpclose() at shutdown.
 *
 * XA: the connection is opened once by tpopen() (ECPG XA switch libndrxxaecpg.so);
 * there is NO EXEC SQL CONNECT. Each tpcall runs on this process's XA branch.
 */
#include <atmi.h>
#include <ubf.h>
#include <userlog.h>

/* every mg service's copybook header (declares its prototype) */
#include "MG_RECV.h"
#include "MG_SEND.h"
#include "MG_ISO8583.h"
#include "MG_BITMAP.h"
#include "MG_STAN.h"
#include "MG_ROUTE.h"
#include "MG_RESEND.h"
#include "MG_CONVERT.h"
#include "MG_ERRMSG.h"
#include "MG_LOG.h"
#include "MG_CLEARING_INQ.h"
#include "MG_CHANAUTH.h"
#include "MG_SESSION.h"
#include "MG_ACK.h"
#include "MG_NACK.h"
#include "MG_ECHO.h"
#include "MG_HEALTH.h"
#include "MG_SIGNON.h"
#include "MG_SIGNOFF.h"
#include "MG_KEYEXCH.h"
#include "MG_MAC.h"
#include "MG_PARSE.h"
#include "MG_PACK.h"
#include "MG_UNPACK.h"
#include "MG_QUEUE.h"
#include "MG_DEQUEUE.h"
#include "MG_RETRY.h"
#include "MG_STATS.h"
#include "MG_CHANSTAT.h"
#include "MG_STATUS.h"
#include "MG_CONFIRM.h"
/* --- 전문유형별 처리 (0100/0110/0200/0210/0400/0420/0800) --- */
#include "MG_AUTHREQ.h"
#include "MG_AUTHRSP.h"
#include "MG_CAPTURE.h"
#include "MG_CAPRSP.h"
#include "MG_REVERSAL.h"
#include "MG_REVADVICE.h"
#include "MG_NETMGMT.h"
/* --- 채널별 어댑터 / 전문 재조립 --- */
#include "MG_VAN1ADPT.h"
#include "MG_VAN2ADPT.h"
#include "MG_DIRECTADPT.h"
#include "MG_REASM.h"
/* --- MAC 세분 / 키 관리 --- */
#include "MG_MACGEN.h"
#include "MG_MACVERIFY.h"
#include "MG_KEYROTATE.h"
#include "MG_KEYSTATUS.h"
/* --- 타임아웃 / 중복·순번 검출 --- */
#include "MG_TIMEOUT.h"
#include "MG_TIMEOUTSET.h"
#include "MG_DUPCHK.h"
#include "MG_GAPSCAN.h"
#include "MG_SEQAUDIT.h"
/* --- 전문 변환 (내부<->ISO) / 라우팅 룰 관리 --- */
#include "MG_TOISO.h"
#include "MG_FROMISO.h"
#include "MG_RTADD.h"
#include "MG_RTDROP.h"
#include "MG_RTLIST.h"
#include "MG_RTSWITCH.h"
/* --- 채널 상태 모니터/절체 --- */
#include "MG_CHANOPEN.h"
#include "MG_CHANCLOSE.h"
#include "MG_CHANSWITCH.h"
#include "MG_CHANHEALTH.h"
/* --- 전문 통계 세분 --- */
#include "MG_STATMTI.h"
#include "MG_STATHOUR.h"
#include "MG_STATDIR.h"
#include "MG_STATRC.h"
/* --- 오류전문 재처리 워크플로 / 트래픽 제어 --- */
#include "MG_ERRRETRY.h"
#include "MG_ERRLIST.h"
#include "MG_ERRPURGE.h"
#include "MG_THROTTLE.h"
#include "MG_TPSCHECK.h"
/* --- 검증·마스킹 / 정산집계 전문 / 큐 모니터 --- */
#include "MG_PANMASK.h"
#include "MG_AMTCHECK.h"
#include "MG_ADVICE.h"
#include "MG_SETTLEREQ.h"
#include "MG_SETTLERSP.h"
#include "MG_QDEPTH.h"
/* ===== 스케일아웃 신규 서비스 (+58) ===== */
/* --- 전문유형별 처리 세분 (0100/0110/0120/0200/0210/0220/0400/0420/0800/0810) --- */
#include "MG_AUTHADV.h"
#include "MG_AUTHADVRSP.h"
#include "MG_FINREQ.h"
#include "MG_FINRSP.h"
#include "MG_FINADV.h"
#include "MG_FINADVRSP.h"
#include "MG_REVRSP.h"
#include "MG_REVADVRSP.h"
#include "MG_NMRSP.h"
#include "MG_NMADVICE.h"
#include "MG_BALINQ.h"
#include "MG_INQRSP.h"
#include "MG_CARDVER.h"
#include "MG_PREAUTH.h"
/* --- 채널별 어댑터 (VAN사별/직연동/중계) --- */
#include "MG_VAN3ADPT.h"
#include "MG_VAN4ADPT.h"
#include "MG_RELAYADPT.h"
#include "MG_ISOADPT.h"
#include "MG_HOSTADPT.h"
#include "MG_CHANMAP.h"
#include "MG_FEP.h"
/* --- 전문 조립/분해/변환 (내부<->ISO8583) --- */
#include "MG_ENCODE.h"
#include "MG_DECODE.h"
#include "MG_FIELDGET.h"
#include "MG_FIELDSET.h"
#include "MG_BMPPARSE.h"
#include "MG_BMPMERGE.h"
/* --- MAC/키 관리 세분 --- */
#include "MG_MACSESSION.h"
#include "MG_KEYLOAD.h"
#include "MG_KEYCHECK.h"
#include "MG_PINBLOCK.h"
#include "MG_KEYEXPIRE.h"
/* --- 타임아웃/재전송/중복검출 세분 --- */
#include "MG_RESNDONE.h"
#include "MG_STALEMARK.h"
#include "MG_DUPPURGE.h"
#include "MG_INFLIGHT.h"
/* --- 순번 갭 검출/보정 --- */
#include "MG_SEQNEXT.h"
#include "MG_SEQRESET.h"
#include "MG_SEQFILL.h"
/* --- 라우팅 룰 관리 --- */
#include "MG_RTFIND.h"
#include "MG_RTDISABLE.h"
#include "MG_RTENABLE.h"
#include "MG_RTCOUNT.h"
/* --- 채널 상태 모니터/이중화 전환 --- */
#include "MG_CHANPING.h"
#include "MG_CHANFAILOVER.h"
#include "MG_CHANLIST.h"
#include "MG_CHANRESET.h"
/* --- 전문 통계 (채널/금액/응답코드/시간대/종합) --- */
#include "MG_STATCHAN.h"
#include "MG_STATAMT.h"
#include "MG_STATERR.h"
#include "MG_STATPEAK.h"
#include "MG_STATSUM.h"
/* --- 오류전문 재처리 워크플로 --- */
#include "MG_ERRREQUEUE.h"
#include "MG_ERRCLASS.h"
#include "MG_ERRESCAL.h"
/* --- 트래픽 제어/부하분산 + 헬스체크 세분 --- */
#include "MG_LOADBAL.h"
#include "MG_RATELIMIT.h"
#include "MG_READYZ.h"

/* ----- advertise table: {service name, function} (fn is extern from its file) */
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
    {"MG_RECV", MG_RECV},             {"MG_SEND", MG_SEND},
    {"MG_ISO8583", MG_ISO8583},       {"MG_BITMAP", MG_BITMAP},
    {"MG_STAN", MG_STAN},             {"MG_ROUTE", MG_ROUTE},
    {"MG_RESEND", MG_RESEND},         {"MG_CONVERT", MG_CONVERT},
    {"MG_ERRMSG", MG_ERRMSG},         {"MG_LOG", MG_LOG},
    {"MG_CLEARING_INQ", MG_CLEARING_INQ},
    {"MG_CHANAUTH", MG_CHANAUTH},     {"MG_SESSION", MG_SESSION},
    {"MG_ACK", MG_ACK},               {"MG_NACK", MG_NACK},
    {"MG_ECHO", MG_ECHO},             {"MG_HEALTH", MG_HEALTH},
    {"MG_SIGNON", MG_SIGNON},         {"MG_SIGNOFF", MG_SIGNOFF},
    {"MG_KEYEXCH", MG_KEYEXCH},       {"MG_MAC", MG_MAC},
    {"MG_PARSE", MG_PARSE},           {"MG_PACK", MG_PACK},
    {"MG_UNPACK", MG_UNPACK},         {"MG_QUEUE", MG_QUEUE},
    {"MG_DEQUEUE", MG_DEQUEUE},       {"MG_RETRY", MG_RETRY},
    {"MG_STATS", MG_STATS},           {"MG_CHANSTAT", MG_CHANSTAT},
    {"MG_STATUS", MG_STATUS},         {"MG_CONFIRM", MG_CONFIRM},
    {"MG_AUTHREQ", MG_AUTHREQ},       {"MG_AUTHRSP", MG_AUTHRSP},
    {"MG_CAPTURE", MG_CAPTURE},       {"MG_CAPRSP", MG_CAPRSP},
    {"MG_REVERSAL", MG_REVERSAL},     {"MG_REVADVICE", MG_REVADVICE},
    {"MG_NETMGMT", MG_NETMGMT},       {"MG_VAN1ADPT", MG_VAN1ADPT},
    {"MG_VAN2ADPT", MG_VAN2ADPT},     {"MG_DIRECTADPT", MG_DIRECTADPT},
    {"MG_REASM", MG_REASM},           {"MG_MACGEN", MG_MACGEN},
    {"MG_MACVERIFY", MG_MACVERIFY},   {"MG_KEYROTATE", MG_KEYROTATE},
    {"MG_KEYSTATUS", MG_KEYSTATUS},   {"MG_TIMEOUT", MG_TIMEOUT},
    {"MG_TIMEOUTSET", MG_TIMEOUTSET}, {"MG_DUPCHK", MG_DUPCHK},
    {"MG_GAPSCAN", MG_GAPSCAN},       {"MG_SEQAUDIT", MG_SEQAUDIT},
    {"MG_TOISO", MG_TOISO},           {"MG_FROMISO", MG_FROMISO},
    {"MG_RTADD", MG_RTADD},           {"MG_RTDROP", MG_RTDROP},
    {"MG_RTLIST", MG_RTLIST},         {"MG_RTSWITCH", MG_RTSWITCH},
    {"MG_CHANOPEN", MG_CHANOPEN},     {"MG_CHANCLOSE", MG_CHANCLOSE},
    {"MG_CHANSWITCH", MG_CHANSWITCH}, {"MG_CHANHEALTH", MG_CHANHEALTH},
    {"MG_STATMTI", MG_STATMTI},       {"MG_STATHOUR", MG_STATHOUR},
    {"MG_STATDIR", MG_STATDIR},       {"MG_STATRC", MG_STATRC},
    {"MG_ERRRETRY", MG_ERRRETRY},     {"MG_ERRLIST", MG_ERRLIST},
    {"MG_ERRPURGE", MG_ERRPURGE},     {"MG_THROTTLE", MG_THROTTLE},
    {"MG_TPSCHECK", MG_TPSCHECK},     {"MG_PANMASK", MG_PANMASK},
    {"MG_AMTCHECK", MG_AMTCHECK},     {"MG_ADVICE", MG_ADVICE},
    {"MG_SETTLEREQ", MG_SETTLEREQ},   {"MG_SETTLERSP", MG_SETTLERSP},
    {"MG_QDEPTH", MG_QDEPTH},
    /* ===== 스케일아웃 신규 서비스 (+58) ===== */
    {"MG_AUTHADV", MG_AUTHADV},         {"MG_AUTHADVRSP", MG_AUTHADVRSP},
    {"MG_FINREQ", MG_FINREQ},           {"MG_FINRSP", MG_FINRSP},
    {"MG_FINADV", MG_FINADV},           {"MG_FINADVRSP", MG_FINADVRSP},
    {"MG_REVRSP", MG_REVRSP},           {"MG_REVADVRSP", MG_REVADVRSP},
    {"MG_NMRSP", MG_NMRSP},             {"MG_NMADVICE", MG_NMADVICE},
    {"MG_BALINQ", MG_BALINQ},           {"MG_INQRSP", MG_INQRSP},
    {"MG_CARDVER", MG_CARDVER},         {"MG_PREAUTH", MG_PREAUTH},
    {"MG_VAN3ADPT", MG_VAN3ADPT},       {"MG_VAN4ADPT", MG_VAN4ADPT},
    {"MG_RELAYADPT", MG_RELAYADPT},     {"MG_ISOADPT", MG_ISOADPT},
    {"MG_HOSTADPT", MG_HOSTADPT},       {"MG_CHANMAP", MG_CHANMAP},
    {"MG_FEP", MG_FEP},                 {"MG_ENCODE", MG_ENCODE},
    {"MG_DECODE", MG_DECODE},           {"MG_FIELDGET", MG_FIELDGET},
    {"MG_FIELDSET", MG_FIELDSET},       {"MG_BMPPARSE", MG_BMPPARSE},
    {"MG_BMPMERGE", MG_BMPMERGE},       {"MG_MACSESSION", MG_MACSESSION},
    {"MG_KEYLOAD", MG_KEYLOAD},         {"MG_KEYCHECK", MG_KEYCHECK},
    {"MG_PINBLOCK", MG_PINBLOCK},       {"MG_KEYEXPIRE", MG_KEYEXPIRE},
    {"MG_RESNDONE", MG_RESNDONE},       {"MG_STALEMARK", MG_STALEMARK},
    {"MG_DUPPURGE", MG_DUPPURGE},       {"MG_INFLIGHT", MG_INFLIGHT},
    {"MG_SEQNEXT", MG_SEQNEXT},         {"MG_SEQRESET", MG_SEQRESET},
    {"MG_SEQFILL", MG_SEQFILL},         {"MG_RTFIND", MG_RTFIND},
    {"MG_RTDISABLE", MG_RTDISABLE},     {"MG_RTENABLE", MG_RTENABLE},
    {"MG_RTCOUNT", MG_RTCOUNT},         {"MG_CHANPING", MG_CHANPING},
    {"MG_CHANFAILOVER", MG_CHANFAILOVER}, {"MG_CHANLIST", MG_CHANLIST},
    {"MG_CHANRESET", MG_CHANRESET},     {"MG_STATCHAN", MG_STATCHAN},
    {"MG_STATAMT", MG_STATAMT},         {"MG_STATERR", MG_STATERR},
    {"MG_STATPEAK", MG_STATPEAK},       {"MG_STATSUM", MG_STATSUM},
    {"MG_ERRREQUEUE", MG_ERRREQUEUE},   {"MG_ERRCLASS", MG_ERRCLASS},
    {"MG_ERRESCAL", MG_ERRESCAL},       {"MG_LOADBAL", MG_LOADBAL},
    {"MG_RATELIMIT", MG_RATELIMIT},     {"MG_READYZ", MG_READYZ},
    {NULL, NULL}
};

int tpsvrinit(int argc, char **argv)
{
    int i;
    if (tpopen() < 0) {
        userlog("mg_svr: tpopen FAIL: %s", tpstrerror(tperrno));
        return -1;
    }
    for (i = 0; SVCS[i].name != NULL; i++) {
        if (tpadvertise((char *)SVCS[i].name, SVCS[i].fn) < 0) {
            userlog("mg_svr: tpadvertise(%s) FAIL: %s", SVCS[i].name, tpstrerror(tperrno));
            return -1;
        }
    }
    userlog("mg_svr: %d mg 서비스 광고 완료, RM 오픈", i);
    return 0;
}

void tpsvrdone(void)
{
    tpclose();
    userlog("mg_svr: tpsvrdone");
}

/* vim: set ts=4 sw=4 et smartindent: */
