/*
 * cm_svr.pgc - cm (공통 / common) MODULE SERVER (thin dispatcher).
 *
 * The legacy "one module server, many services" pattern: this binary owns NO
 * business logic. Each of cm's 30 online services now lives in its own file
 * (app/src/cm/svc/<SVCNAME>.pgc) with its own copybook header
 * (app/src/cm/svc/<SVCNAME>.h); those objects are archived into libcmsvc.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 cm service's copybook header (declares its prototype) */
#include "CM_CODE.h"
#include "CM_CODENAME.h"
#include "CM_BIZDAY.h"
#include "CM_NEXTBIZ.h"
#include "CM_ADDDAYS.h"
#include "CM_WEEKDAY.h"
#include "CM_MONTHEND.h"
#include "CM_AMT_ROUND.h"
#include "CM_AMT_SPLIT.h"
#include "CM_SEQ.h"
#include "CM_FX.h"
#include "CM_FX_CONV.h"
#include "CM_LUHN.h"
#include "CM_CRC.h"
#include "CM_MASK.h"
#include "CM_FMT_DATE.h"
#include "CM_FMT_AMT.h"
#include "CM_PARAM.h"
#include "CM_PARAM_SET.h"
#include "CM_CACHE_LOAD.h"
#include "CM_CACHE_INV.h"
#include "CM_ERRMSG.h"
#include "CM_LOG.h"
#include "CM_HOLIDAY_CHK.h"
#include "CM_CHECKDIGIT.h"
#include "CM_INTEREST.h"
#include "CM_PRORATE.h"
#include "CM_NETTING_CALC.h"
#include "CM_STATUS.h"
#include "CM_PING.h"

/* ----- advertise table: {service name, function} (fn is extern from its file) */
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
    {"CM_CODE", CM_CODE},             {"CM_CODENAME", CM_CODENAME},
    {"CM_BIZDAY", CM_BIZDAY},         {"CM_NEXTBIZ", CM_NEXTBIZ},
    {"CM_ADDDAYS", CM_ADDDAYS},       {"CM_WEEKDAY", CM_WEEKDAY},
    {"CM_MONTHEND", CM_MONTHEND},     {"CM_AMT_ROUND", CM_AMT_ROUND},
    {"CM_AMT_SPLIT", CM_AMT_SPLIT},   {"CM_SEQ", CM_SEQ},
    {"CM_FX", CM_FX},                 {"CM_FX_CONV", CM_FX_CONV},
    {"CM_LUHN", CM_LUHN},             {"CM_CRC", CM_CRC},
    {"CM_MASK", CM_MASK},             {"CM_FMT_DATE", CM_FMT_DATE},
    {"CM_FMT_AMT", CM_FMT_AMT},       {"CM_PARAM", CM_PARAM},
    {"CM_PARAM_SET", CM_PARAM_SET},   {"CM_CACHE_LOAD", CM_CACHE_LOAD},
    {"CM_CACHE_INV", CM_CACHE_INV},   {"CM_ERRMSG", CM_ERRMSG},
    {"CM_LOG", CM_LOG},               {"CM_HOLIDAY_CHK", CM_HOLIDAY_CHK},
    {"CM_CHECKDIGIT", CM_CHECKDIGIT}, {"CM_INTEREST", CM_INTEREST},
    {"CM_PRORATE", CM_PRORATE},       {"CM_NETTING_CALC", CM_NETTING_CALC},
    {"CM_STATUS", CM_STATUS},         {"CM_PING", CM_PING},
    {NULL, NULL}
};

int tpsvrinit(int argc, char **argv)
{
    int i;
    if (tpopen() < 0) {
        userlog("cm_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("cm_svr: tpadvertise(%s) FAIL: %s", SVCS[i].name, tpstrerror(tperrno));
            return -1;
        }
    }
    userlog("cm_svr: %d cm 서비스 광고 완료, RM 오픈", i);
    return 0;
}

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

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