/*
 * mm_svr.pgc - mm (마스터/master) MODULE SERVER (thin dispatcher).
 *
 * The legacy "one module server, many services" pattern: this binary owns NO
 * business logic. Each of mm's ~30 online services now lives in its own file
 * (app/src/mm/svc/<SVCNAME>.pgc) with its own copybook header
 * (app/src/mm/svc/<SVCNAME>.h); those objects are archived into libmmsvc.a and
 * linked into this server. Here we only include every service copybook, tpopen()
 * the ECPG XA RM, tpadvertise() all services from a {name, fn} table, tpclose().
 *
 * 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 mm service's copybook header (declares its prototype) */
#include "MM_MERCH_REG.h"
#include "MM_MERCH_UPD.h"
#include "MM_MERCH_INQ.h"
#include "MM_MERCH_DEL.h"
#include "MM_FEERATE_SET.h"
#include "MM_FEERATE_INQ.h"
#include "MM_FEERATE_HIST.h"
#include "MM_BIN_REG.h"
#include "MM_BIN_INQ.h"
#include "MM_LIMIT_SET.h"
#include "MM_LIMIT_INQ.h"
#include "MM_CODE_REG.h"
#include "MM_CODE_INQ.h"
#include "MM_ISSUER_REG.h"
#include "MM_ISSUER_INQ.h"
#include "MM_MERCH_STATUS.h"
#include "MM_MERCH_ACCT.h"
#include "MM_MERCH_GRADE.h"
#include "MM_TERMINAL_REG.h"
#include "MM_TERMINAL_INQ.h"
#include "MM_MCC_REG.h"
#include "MM_HOLIDAY_REG.h"
#include "MM_FX_REG.h"
#include "MM_FX_INQ.h"
#include "MM_MERCH_BULK.h"
#include "MM_VALIDATE.h"
#include "MM_MERCH_SUM.h"
#include "MM_CODE_CACHE.h"
#include "MM_STATUS.h"
#include "MM_CONFIRM.h"

/* ----- advertise table: {service name, function} (fn is extern from its file) */
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
    {"MM_MERCH_REG", MM_MERCH_REG},
    {"MM_MERCH_UPD", MM_MERCH_UPD},
    {"MM_MERCH_INQ", MM_MERCH_INQ},
    {"MM_MERCH_DEL", MM_MERCH_DEL},
    {"MM_FEERATE_SET", MM_FEERATE_SET},
    {"MM_FEERATE_INQ", MM_FEERATE_INQ},
    {"MM_FEERATE_HIST", MM_FEERATE_HIST},
    {"MM_BIN_REG", MM_BIN_REG},
    {"MM_BIN_INQ", MM_BIN_INQ},
    {"MM_LIMIT_SET", MM_LIMIT_SET},
    {"MM_LIMIT_INQ", MM_LIMIT_INQ},
    {"MM_CODE_REG", MM_CODE_REG},
    {"MM_CODE_INQ", MM_CODE_INQ},
    {"MM_ISSUER_REG", MM_ISSUER_REG},
    {"MM_ISSUER_INQ", MM_ISSUER_INQ},
    {"MM_MERCH_STATUS", MM_MERCH_STATUS},
    {"MM_MERCH_ACCT", MM_MERCH_ACCT},
    {"MM_MERCH_GRADE", MM_MERCH_GRADE},
    {"MM_TERMINAL_REG", MM_TERMINAL_REG},
    {"MM_TERMINAL_INQ", MM_TERMINAL_INQ},
    {"MM_MCC_REG", MM_MCC_REG},
    {"MM_HOLIDAY_REG", MM_HOLIDAY_REG},
    {"MM_FX_REG", MM_FX_REG},
    {"MM_FX_INQ", MM_FX_INQ},
    {"MM_MERCH_BULK", MM_MERCH_BULK},
    {"MM_VALIDATE", MM_VALIDATE},
    {"MM_MERCH_SUM", MM_MERCH_SUM},
    {"MM_CODE_CACHE", MM_CODE_CACHE},
    {"MM_STATUS", MM_STATUS},
    {"MM_CONFIRM", MM_CONFIRM},
    {NULL, NULL}
};

int tpsvrinit(int argc, char **argv)
{
    int i;
    if (tpopen() < 0) {
        userlog("mm_svr: tpopen 실패: %s", tpstrerror(tperrno));
        return -1;
    }
    for (i = 0; SVCS[i].name != NULL; i++) {
        if (tpadvertise((char *)SVCS[i].name, SVCS[i].fn) < 0) {
            userlog("mm_svr: tpadvertise(%s) 실패: %s", SVCS[i].name, tpstrerror(tperrno));
            return -1;
        }
    }
    userlog("mm_svr: mm 마스터 서비스 %d개 광고 완료, RM open", i);
    return 0;
}

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

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