/*
 * 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 133 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"
#include "LG_ACCTLEDGER.h"
#include "LG_ACCTRANGE.h"
#include "LG_MONTHCLOSE.h"
#include "LG_QTRCLOSE.h"
#include "LG_REDENTRY.h"
#include "LG_BLACKENTRY.h"
#include "LG_PENDLIST.h"
#include "LG_PENDAGE.h"
#include "LG_APPROVE.h"
#include "LG_REJECT.h"
#include "LG_APPRQUEUE.h"
#include "LG_DEPTPL.h"
#include "LG_FEERECOG.h"
#include "LG_FEEACCRUE.h"
#include "LG_RECVACCRUE.h"
#include "LG_PAYACCRUE.h"
#include "LG_BADDEBT.h"
#include "LG_BADDEBTRCV.h"
#include "LG_SETTLERECON.h"
#include "LG_PAYRECON.h"
#include "LG_BALPROOF.h"
#include "LG_MERCHPROOF.h"
#include "LG_PERIODTB.h"
#include "LG_MASKINQ.h"
#include "LG_CLOSECHK.h"
#include "LG_STATDC.h"
#include "LG_STATACCT.h"
#include "LG_STATTYPE.h"
#include "LG_STATMERCH.h"
#include "LG_VOIDVOUCHER.h"
#include "LG_REOPEN.h"
#include "LG_ACCTHIST.h"
#include "LG_DAYCLOSE.h"
#include "LG_NETPOS.h"
#include "LG_LINECOUNT.h"
#include "LG_BIGLINE.h"
#include "LG_SUSPENSE.h"
#include "LG_ACCRUEREV.h"
#include "LG_FEESPLIT.h"
#include "LG_PLCLOSE.h"
#include "LG_TBDIFF.h"
#include "LG_VOUCHTRACE.h"
#include "LG_MEMOAUDIT.h"
#include "LG_ZEROLINE.h"
#include "LG_DUPSCAN.h"
#include "LG_DEPTLEDGER.h"
#include "LG_CORPLEDGER.h"
#include "LG_ACCTGROUP.h"
#include "LG_DEPTSUM.h"
#include "LG_CORPSUM.h"
#include "LG_ACCTPIVOT.h"
#include "LG_DEPTRANGE.h"
#include "LG_ACCTTOPN.h"
#include "LG_HALFCLOSE.h"
#include "LG_YEARCLOSE.h"
#include "LG_WEEKCLOSE.h"
#include "LG_MONCLOSEJE.h"
#include "LG_QTRCLOSEJE.h"
#include "LG_YEARCARRY.h"
#include "LG_REDADJUST.h"
#include "LG_BLACKADJUST.h"
#include "LG_REDBLACKNET.h"
#include "LG_CORRPAIR.h"
#include "LG_PENDCLEAR.h"
#include "LG_PENDROUTE.h"
#include "LG_PENDESCAL.h"
#include "LG_PENDSTAT.h"
#include "LG_BATCHAPPROVE.h"
#include "LG_APPRDELEG.h"
#include "LG_APPRHIST.h"
#include "LG_UNAPPROVE.h"
#include "LG_PLSUMMARY.h"
#include "LG_BSSUMMARY.h"
#include "LG_INCOMEROLL.h"
#include "LG_EXPENSEROLL.h"
#include "LG_EQUITYMOVE.h"
#include "LG_REVACCRUE.h"
#include "LG_REVDEFER.h"
#include "LG_REVRELEASE.h"
#include "LG_UNEARNRECOG.h"
#include "LG_ACCRUEDRECV.h"
#include "LG_ACCRUEDPAY.h"
#include "LG_PREPAIDPOST.h"
#include "LG_UNEARNPOST.h"
#include "LG_PREPAIDAMORT.h"
#include "LG_ALLOWANCE.h"
#include "LG_WRITEOFF.h"
#include "LG_RECOVERY.h"
#include "LG_ALLOWRECALC.h"
#include "LG_THREEWAY.h"
#include "LG_PAYMATCH.h"
#include "LG_LEDGSETTLE.h"
#include "LG_SETTLEPAYGAP.h"
#include "LG_BALCERT.h"
#include "LG_MERCHCERT.h"
#include "LG_SPANTB.h"
#include "LG_ROLLTB.h"
#include "LG_PARTREVERSE.h"
#include "LG_REPOST.h"
#include "LG_XFERPOST.h"
#include "LG_AUDITSCAN.h"
#include "LG_SEQAUDIT.h"
#include "LG_CLOSELIST.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},
    {"LG_ACCTLEDGER", LG_ACCTLEDGER},{"LG_ACCTRANGE", LG_ACCTRANGE},
    {"LG_MONTHCLOSE", LG_MONTHCLOSE},{"LG_QTRCLOSE", LG_QTRCLOSE},
    {"LG_REDENTRY", LG_REDENTRY},   {"LG_BLACKENTRY", LG_BLACKENTRY},
    {"LG_PENDLIST", LG_PENDLIST},   {"LG_PENDAGE", LG_PENDAGE},
    {"LG_APPROVE", LG_APPROVE},     {"LG_REJECT", LG_REJECT},
    {"LG_APPRQUEUE", LG_APPRQUEUE}, {"LG_DEPTPL", LG_DEPTPL},
    {"LG_FEERECOG", LG_FEERECOG},   {"LG_FEEACCRUE", LG_FEEACCRUE},
    {"LG_RECVACCRUE", LG_RECVACCRUE},{"LG_PAYACCRUE", LG_PAYACCRUE},
    {"LG_BADDEBT", LG_BADDEBT},     {"LG_BADDEBTRCV", LG_BADDEBTRCV},
    {"LG_SETTLERECON", LG_SETTLERECON},{"LG_PAYRECON", LG_PAYRECON},
    {"LG_BALPROOF", LG_BALPROOF},   {"LG_MERCHPROOF", LG_MERCHPROOF},
    {"LG_PERIODTB", LG_PERIODTB},   {"LG_MASKINQ", LG_MASKINQ},
    {"LG_CLOSECHK", LG_CLOSECHK},   {"LG_STATDC", LG_STATDC},
    {"LG_STATACCT", LG_STATACCT},   {"LG_STATTYPE", LG_STATTYPE},
    {"LG_STATMERCH", LG_STATMERCH}, {"LG_VOIDVOUCHER", LG_VOIDVOUCHER},
    {"LG_REOPEN", LG_REOPEN},       {"LG_ACCTHIST", LG_ACCTHIST},
    {"LG_DAYCLOSE", LG_DAYCLOSE},   {"LG_NETPOS", LG_NETPOS},
    {"LG_LINECOUNT", LG_LINECOUNT}, {"LG_BIGLINE", LG_BIGLINE},
    {"LG_SUSPENSE", LG_SUSPENSE},   {"LG_ACCRUEREV", LG_ACCRUEREV},
    {"LG_FEESPLIT", LG_FEESPLIT},   {"LG_PLCLOSE", LG_PLCLOSE},
    {"LG_TBDIFF", LG_TBDIFF},       {"LG_VOUCHTRACE", LG_VOUCHTRACE},
    {"LG_MEMOAUDIT", LG_MEMOAUDIT}, {"LG_ZEROLINE", LG_ZEROLINE},
    {"LG_DUPSCAN", LG_DUPSCAN},
    {"LG_DEPTLEDGER", LG_DEPTLEDGER},
    {"LG_CORPLEDGER", LG_CORPLEDGER},
    {"LG_ACCTGROUP", LG_ACCTGROUP},
    {"LG_DEPTSUM", LG_DEPTSUM},
    {"LG_CORPSUM", LG_CORPSUM},
    {"LG_ACCTPIVOT", LG_ACCTPIVOT},
    {"LG_DEPTRANGE", LG_DEPTRANGE},
    {"LG_ACCTTOPN", LG_ACCTTOPN},
    {"LG_HALFCLOSE", LG_HALFCLOSE},
    {"LG_YEARCLOSE", LG_YEARCLOSE},
    {"LG_WEEKCLOSE", LG_WEEKCLOSE},
    {"LG_MONCLOSEJE", LG_MONCLOSEJE},
    {"LG_QTRCLOSEJE", LG_QTRCLOSEJE},
    {"LG_YEARCARRY", LG_YEARCARRY},
    {"LG_REDADJUST", LG_REDADJUST},
    {"LG_BLACKADJUST", LG_BLACKADJUST},
    {"LG_REDBLACKNET", LG_REDBLACKNET},
    {"LG_CORRPAIR", LG_CORRPAIR},
    {"LG_PENDCLEAR", LG_PENDCLEAR},
    {"LG_PENDROUTE", LG_PENDROUTE},
    {"LG_PENDESCAL", LG_PENDESCAL},
    {"LG_PENDSTAT", LG_PENDSTAT},
    {"LG_BATCHAPPROVE", LG_BATCHAPPROVE},
    {"LG_APPRDELEG", LG_APPRDELEG},
    {"LG_APPRHIST", LG_APPRHIST},
    {"LG_UNAPPROVE", LG_UNAPPROVE},
    {"LG_PLSUMMARY", LG_PLSUMMARY},
    {"LG_BSSUMMARY", LG_BSSUMMARY},
    {"LG_INCOMEROLL", LG_INCOMEROLL},
    {"LG_EXPENSEROLL", LG_EXPENSEROLL},
    {"LG_EQUITYMOVE", LG_EQUITYMOVE},
    {"LG_REVACCRUE", LG_REVACCRUE},
    {"LG_REVDEFER", LG_REVDEFER},
    {"LG_REVRELEASE", LG_REVRELEASE},
    {"LG_UNEARNRECOG", LG_UNEARNRECOG},
    {"LG_ACCRUEDRECV", LG_ACCRUEDRECV},
    {"LG_ACCRUEDPAY", LG_ACCRUEDPAY},
    {"LG_PREPAIDPOST", LG_PREPAIDPOST},
    {"LG_UNEARNPOST", LG_UNEARNPOST},
    {"LG_PREPAIDAMORT", LG_PREPAIDAMORT},
    {"LG_ALLOWANCE", LG_ALLOWANCE},
    {"LG_WRITEOFF", LG_WRITEOFF},
    {"LG_RECOVERY", LG_RECOVERY},
    {"LG_ALLOWRECALC", LG_ALLOWRECALC},
    {"LG_THREEWAY", LG_THREEWAY},
    {"LG_PAYMATCH", LG_PAYMATCH},
    {"LG_LEDGSETTLE", LG_LEDGSETTLE},
    {"LG_SETTLEPAYGAP", LG_SETTLEPAYGAP},
    {"LG_BALCERT", LG_BALCERT},
    {"LG_MERCHCERT", LG_MERCHCERT},
    {"LG_SPANTB", LG_SPANTB},
    {"LG_ROLLTB", LG_ROLLTB},
    {"LG_PARTREVERSE", LG_PARTREVERSE},
    {"LG_REPOST", LG_REPOST},
    {"LG_XFERPOST", LG_XFERPOST},
    {"LG_AUDITSCAN", LG_AUDITSCAN},
    {"LG_SEQAUDIT", LG_SEQAUDIT},
    {"LG_CLOSELIST", LG_CLOSELIST},
    {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: */
