/*
 * lg_svr.pgc - lg (원장/ledger) MODULE SERVER (thin dispatcher).
 *
 * The legacy "one module server, many services" pattern: this binary owns NO
 * business logic. Each of lg's 30 online services now lives in its own file
 * (app/src/lg/svc/<SVCNAME>.pgc) with its own copybook header
 * (app/src/lg/svc/<SVCNAME>.h); those objects are archived into liblgsvc.a and
 * linked into this server. Here we only:
 *   - include every service copybook (for the extern prototypes),
 *   - tpopen() the ECPG XA RM,
 *   - tpadvertise() all services from a {name, fn} table,
 *   - tpclose() at shutdown.
 *
 * 복식부기 원칙: 모든 전표는 차변(D) 합 = 대변(C) 합. 계정잔액 balance = 차변-대변.
 * 모든 전기(posting)는 대변/차변 균형 분개로 이루어진다.
 *
 * 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 lg service's copybook header (declares its record struct + prototype) */
#include "LG_POST.h"
#include "LG_CREDIT.h"
#include "LG_DEBIT.h"
#include "LG_DOUBLE.h"
#include "LG_BALCHK.h"
#include "LG_REVERSE.h"
#include "LG_CARRY.h"
#include "LG_CLOSE_LINK.h"
#include "LG_ACCTSUM.h"
#include "LG_RECALC.h"
#include "LG_UNSETTLED.h"
#include "LG_STATS.h"
#include "LG_DIFFCHK.h"
#include "LG_CORRECT.h"
#include "LG_INQUIRY.h"
#include "LG_TRIALBAL.h"
#include "LG_JOURNAL.h"
#include "LG_VOUCHER.h"
#include "LG_APPLY.h"
#include "LG_ROLLFWD.h"
#include "LG_MERCHBAL.h"
#include "LG_DAILYSUM.h"
#include "LG_MONTHLYSUM.h"
#include "LG_ADJUST.h"
#include "LG_TRANSFER.h"
#include "LG_SETTLEPOST.h"
#include "LG_ACQPOST.h"
#include "LG_FEEPOST.h"
#include "LG_STATUS.h"
#include "LG_CONFIRM.h"

/* ----- advertise table: {service name, function} (fn is extern from its file) */
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
    {"LG_POST", LG_POST},           {"LG_CREDIT", LG_CREDIT},
    {"LG_DEBIT", LG_DEBIT},         {"LG_DOUBLE", LG_DOUBLE},
    {"LG_BALCHK", LG_BALCHK},       {"LG_REVERSE", LG_REVERSE},
    {"LG_CARRY", LG_CARRY},         {"LG_CLOSE_LINK", LG_CLOSE_LINK},
    {"LG_ACCTSUM", LG_ACCTSUM},     {"LG_RECALC", LG_RECALC},
    {"LG_UNSETTLED", LG_UNSETTLED}, {"LG_STATS", LG_STATS},
    {"LG_DIFFCHK", LG_DIFFCHK},     {"LG_CORRECT", LG_CORRECT},
    {"LG_INQUIRY", LG_INQUIRY},     {"LG_TRIALBAL", LG_TRIALBAL},
    {"LG_JOURNAL", LG_JOURNAL},     {"LG_VOUCHER", LG_VOUCHER},
    {"LG_APPLY", LG_APPLY},         {"LG_ROLLFWD", LG_ROLLFWD},
    {"LG_MERCHBAL", LG_MERCHBAL},   {"LG_DAILYSUM", LG_DAILYSUM},
    {"LG_MONTHLYSUM", LG_MONTHLYSUM},{"LG_ADJUST", LG_ADJUST},
    {"LG_TRANSFER", LG_TRANSFER},   {"LG_SETTLEPOST", LG_SETTLEPOST},
    {"LG_ACQPOST", LG_ACQPOST},     {"LG_FEEPOST", LG_FEEPOST},
    {"LG_STATUS", LG_STATUS},       {"LG_CONFIRM", LG_CONFIRM},
    {NULL, NULL}
};

int tpsvrinit(int argc, char **argv)
{
    int i;
    if (tpopen() < 0) {
        userlog("lg_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("lg_svr: tpadvertise(%s) FAIL: %s", SVCS[i].name, tpstrerror(tperrno));
            return -1;
        }
    }
    userlog("lg_svr: %d lg 서비스 광고 완료, RM 개방 (복식부기 대변/차변)", i);
    return 0;
}

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

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