/*
 * 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 30 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 30 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_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"

/* ----- 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_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},
    {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: */
