/*
 * cl_svr.pgc - cl (마감/closing) MODULE SERVER (thin dispatcher).
 *
 * The legacy "one module server, many services" pattern: this binary owns NO
 * business logic. Each of cl's 133 online services now lives in its own file
 * (app/src/cl/svc/<SVCNAME>.pgc) with its own copybook header
 * (app/src/cl/svc/<SVCNAME>.h); those objects are archived into libclsvc.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.
 *
 * 마감 도메인: 일/월/분기/연 마감 이력(close_log), 가맹점별 마감 스냅샷(snapshot),
 * 기간 잠금(period_lock). 마감 상태 O=개시 -> C=마감완료 -> A=승인 -> L=잠금,
 * 취소 X / 재마감 R.
 *
 * 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 cl service's copybook header (declares its record struct + prototype) */
#include "CL_DAILY.h"
#include "CL_MONTHLY.h"
#include "CL_QUARTER.h"
#include "CL_SNAPSHOT.h"
#include "CL_RECLOSE.h"
#include "CL_VERIFY.h"
#include "CL_CANCEL.h"
#include "CL_STATS.h"
#include "CL_BALVERIFY.h"
#include "CL_SEQ.h"
#include "CL_REPORT.h"
#include "CL_ALERT.h"
#include "CL_UNCLOSED.h"
#include "CL_APPROVE.h"
#include "CL_LOCK.h"
#include "CL_UNLOCK.h"
#include "CL_AGGREGATE.h"
#include "CL_DIFFCHK.h"
#include "CL_SUMMARY.h"
#include "CL_STATUS.h"
#include "CL_ROLLBACK.h"
#include "CL_CONFIRM.h"
#include "CL_PERIOD.h"
#include "CL_YEAREND.h"
#include "CL_MIDCLOSE.h"
#include "CL_RECON.h"
#include "CL_ARCHIVE.h"
#include "CL_PURGE.h"
#include "CL_RESTORE.h"
#include "CL_INQUIRY.h"
#include "CL_CHNCLOSE.h"
#include "CL_DIVCLOSE.h"
#include "CL_CORPCLOSE.h"
#include "CL_PRECHECK.h"
#include "CL_DELAYREG.h"
#include "CL_PROVCLOSE.h"
#include "CL_FINALIZE.h"
#include "CL_APPRREQ.h"
#include "CL_APPRREJECT.h"
#include "CL_APPRHIST.h"
#include "CL_CXLREASON.h"
#include "CL_CNTXCHECK.h"
#include "CL_AMTXCHECK.h"
#include "CL_SNAPXCHECK.h"
#include "CL_RPTCHN.h"
#include "CL_RPTISSUER.h"
#include "CL_RPTCAT.h"
#include "CL_RPTTOPMER.h"
#include "CL_SCHEDULE.h"
#include "CL_HOLIDAY.h"
#include "CL_POSTTRIG.h"
#include "CL_AUDITTRAIL.h"
#include "CL_HALFCLOSE.h"
#include "CL_YEARPREP.h"
#include "CL_SLAMON.h"
#include "CL_DELAYLIST.h"
#include "CL_LOCKSWEEP.h"
#include "CL_LOCKAUDIT.h"
#include "CL_SEQAUDIT.h"
#include "CL_MEMOSEARCH.h"
#include "CL_REOPENREQ.h"
#include "CL_CLOSERATE.h"
#include "CL_GAPDAYS.h"
#include "CL_DUPCHK.h"
#include "CL_TREND.h"
#include "CL_CHNVERIFY.h"
#include "CL_MERCLOSE.h"
#include "CL_FEEVERIFY.h"
#include "CL_NETVERIFY.h"
#include "CL_PENDLIST.h"
#include "CL_ESCALATE.h"
#include "CL_CALENDAR.h"
#include "CL_TRIGSTAT.h"
#include "CL_FORCECLOSE.h"
#include "CL_SNAPDIFF.h"

/* --- cl 마감 확장 서비스 (svc/*.pgc, +58) --- */
#include "CL_WEEKLY.h"
#include "CL_TENDAY.h"
#include "CL_SEMIMONTH.h"
#include "CL_HYCLOSE.h"
#include "CL_DAYVERIFY.h"
#include "CL_WEEKVERIFY.h"
#include "CL_MONVERIFY.h"
#include "CL_QTRVERIFY.h"
#include "CL_YEARVERIFY.h"
#include "CL_HYVERIFY.h"
#include "CL_SEGCLOSE.h"
#include "CL_ISSCLOSE.h"
#include "CL_POSCLOSE.h"
#include "CL_FXCLOSE.h"
#include "CL_SEGVERIFY.h"
#include "CL_CORPVERIFY.h"
#include "CL_CHKUNMATCH.h"
#include "CL_CHKPENDING.h"
#include "CL_CHKVOID.h"
#include "CL_CHKLIMIT.h"
#include "CL_CHKALL.h"
#include "CL_TENTCLOSE.h"
#include "CL_MAINCLOSE.h"
#include "CL_RECLOSEREG.h"
#include "CL_PROVCMP.h"
#include "CL_RECLOSECHK.h"
#include "CL_APPRL1.h"
#include "CL_APPRL2.h"
#include "CL_APPRFINAL.h"
#include "CL_APPRWD.h"
#include "CL_APPRDELEG.h"
#include "CL_APPRSTAT.h"
#include "CL_CXLERROR.h"
#include "CL_CXLLATE.h"
#include "CL_CXLDUP.h"
#include "CL_CXLREQ.h"
#include "CL_CXLSTAT.h"
#include "CL_STCROSS.h"
#include "CL_CNTVERIFY.h"
#include "CL_FEECROSS.h"
#include "CL_NETCROSS.h"
#include "CL_MERXCHECK.h"
#include "CL_RPTDIV.h"
#include "CL_RPTPERIOD.h"
#include "CL_RPTSTATUS.h"
#include "CL_RPTDELAY.h"
#include "CL_RPTAPPR.h"
#include "CL_RPTCXL.h"
#include "CL_SLASET.h"
#include "CL_SLABREACH.h"
#include "CL_SCHEDNEXT.h"
#include "CL_DUELIST.h"
#include "CL_HOLICHK.h"
#include "CL_NEXTBIZ.h"
#include "CL_TRIGSETTLE.h"
#include "CL_TRIGRPT.h"
#include "CL_STCHGAUDIT.h"
#include "CL_SNAPMER.h"

/* ----- advertise table: {service name, function} (fn is extern from its file) */
static struct { const char *name; void (*fn)(TPSVCINFO *); } SVCS[] = {
    {"CL_DAILY", CL_DAILY},         {"CL_MONTHLY", CL_MONTHLY},
    {"CL_QUARTER", CL_QUARTER},     {"CL_SNAPSHOT", CL_SNAPSHOT},
    {"CL_RECLOSE", CL_RECLOSE},     {"CL_VERIFY", CL_VERIFY},
    {"CL_CANCEL", CL_CANCEL},       {"CL_STATS", CL_STATS},
    {"CL_BALVERIFY", CL_BALVERIFY}, {"CL_SEQ", CL_SEQ},
    {"CL_REPORT", CL_REPORT},       {"CL_ALERT", CL_ALERT},
    {"CL_UNCLOSED", CL_UNCLOSED},   {"CL_APPROVE", CL_APPROVE},
    {"CL_LOCK", CL_LOCK},           {"CL_UNLOCK", CL_UNLOCK},
    {"CL_AGGREGATE", CL_AGGREGATE}, {"CL_DIFFCHK", CL_DIFFCHK},
    {"CL_SUMMARY", CL_SUMMARY},     {"CL_STATUS", CL_STATUS},
    {"CL_ROLLBACK", CL_ROLLBACK},   {"CL_CONFIRM", CL_CONFIRM},
    {"CL_PERIOD", CL_PERIOD},       {"CL_YEAREND", CL_YEAREND},
    {"CL_MIDCLOSE", CL_MIDCLOSE},   {"CL_RECON", CL_RECON},
    {"CL_ARCHIVE", CL_ARCHIVE},     {"CL_PURGE", CL_PURGE},
    {"CL_RESTORE", CL_RESTORE},     {"CL_INQUIRY", CL_INQUIRY},
    {"CL_CHNCLOSE", CL_CHNCLOSE},   {"CL_DIVCLOSE", CL_DIVCLOSE},
    {"CL_CORPCLOSE", CL_CORPCLOSE}, {"CL_PRECHECK", CL_PRECHECK},
    {"CL_DELAYREG", CL_DELAYREG},   {"CL_PROVCLOSE", CL_PROVCLOSE},
    {"CL_FINALIZE", CL_FINALIZE},   {"CL_APPRREQ", CL_APPRREQ},
    {"CL_APPRREJECT", CL_APPRREJECT}, {"CL_APPRHIST", CL_APPRHIST},
    {"CL_CXLREASON", CL_CXLREASON}, {"CL_CNTXCHECK", CL_CNTXCHECK},
    {"CL_AMTXCHECK", CL_AMTXCHECK}, {"CL_SNAPXCHECK", CL_SNAPXCHECK},
    {"CL_RPTCHN", CL_RPTCHN},       {"CL_RPTISSUER", CL_RPTISSUER},
    {"CL_RPTCAT", CL_RPTCAT},       {"CL_RPTTOPMER", CL_RPTTOPMER},
    {"CL_SCHEDULE", CL_SCHEDULE},   {"CL_HOLIDAY", CL_HOLIDAY},
    {"CL_POSTTRIG", CL_POSTTRIG},   {"CL_AUDITTRAIL", CL_AUDITTRAIL},
    {"CL_HALFCLOSE", CL_HALFCLOSE}, {"CL_YEARPREP", CL_YEARPREP},
    {"CL_SLAMON", CL_SLAMON},       {"CL_DELAYLIST", CL_DELAYLIST},
    {"CL_LOCKSWEEP", CL_LOCKSWEEP}, {"CL_LOCKAUDIT", CL_LOCKAUDIT},
    {"CL_SEQAUDIT", CL_SEQAUDIT},   {"CL_MEMOSEARCH", CL_MEMOSEARCH},
    {"CL_REOPENREQ", CL_REOPENREQ}, {"CL_CLOSERATE", CL_CLOSERATE},
    {"CL_GAPDAYS", CL_GAPDAYS},     {"CL_DUPCHK", CL_DUPCHK},
    {"CL_TREND", CL_TREND},         {"CL_CHNVERIFY", CL_CHNVERIFY},
    {"CL_MERCLOSE", CL_MERCLOSE},   {"CL_FEEVERIFY", CL_FEEVERIFY},
    {"CL_NETVERIFY", CL_NETVERIFY}, {"CL_PENDLIST", CL_PENDLIST},
    {"CL_ESCALATE", CL_ESCALATE},   {"CL_CALENDAR", CL_CALENDAR},
    {"CL_TRIGSTAT", CL_TRIGSTAT},   {"CL_FORCECLOSE", CL_FORCECLOSE},
    {"CL_SNAPDIFF", CL_SNAPDIFF},
    {"CL_WEEKLY", CL_WEEKLY}, {"CL_TENDAY", CL_TENDAY},
    {"CL_SEMIMONTH", CL_SEMIMONTH}, {"CL_HYCLOSE", CL_HYCLOSE},
    {"CL_DAYVERIFY", CL_DAYVERIFY}, {"CL_WEEKVERIFY", CL_WEEKVERIFY},
    {"CL_MONVERIFY", CL_MONVERIFY}, {"CL_QTRVERIFY", CL_QTRVERIFY},
    {"CL_YEARVERIFY", CL_YEARVERIFY}, {"CL_HYVERIFY", CL_HYVERIFY},
    {"CL_SEGCLOSE", CL_SEGCLOSE}, {"CL_ISSCLOSE", CL_ISSCLOSE},
    {"CL_POSCLOSE", CL_POSCLOSE}, {"CL_FXCLOSE", CL_FXCLOSE},
    {"CL_SEGVERIFY", CL_SEGVERIFY}, {"CL_CORPVERIFY", CL_CORPVERIFY},
    {"CL_CHKUNMATCH", CL_CHKUNMATCH}, {"CL_CHKPENDING", CL_CHKPENDING},
    {"CL_CHKVOID", CL_CHKVOID}, {"CL_CHKLIMIT", CL_CHKLIMIT},
    {"CL_CHKALL", CL_CHKALL}, {"CL_TENTCLOSE", CL_TENTCLOSE},
    {"CL_MAINCLOSE", CL_MAINCLOSE}, {"CL_RECLOSEREG", CL_RECLOSEREG},
    {"CL_PROVCMP", CL_PROVCMP}, {"CL_RECLOSECHK", CL_RECLOSECHK},
    {"CL_APPRL1", CL_APPRL1}, {"CL_APPRL2", CL_APPRL2},
    {"CL_APPRFINAL", CL_APPRFINAL}, {"CL_APPRWD", CL_APPRWD},
    {"CL_APPRDELEG", CL_APPRDELEG}, {"CL_APPRSTAT", CL_APPRSTAT},
    {"CL_CXLERROR", CL_CXLERROR}, {"CL_CXLLATE", CL_CXLLATE},
    {"CL_CXLDUP", CL_CXLDUP}, {"CL_CXLREQ", CL_CXLREQ},
    {"CL_CXLSTAT", CL_CXLSTAT}, {"CL_STCROSS", CL_STCROSS},
    {"CL_CNTVERIFY", CL_CNTVERIFY}, {"CL_FEECROSS", CL_FEECROSS},
    {"CL_NETCROSS", CL_NETCROSS}, {"CL_MERXCHECK", CL_MERXCHECK},
    {"CL_RPTDIV", CL_RPTDIV}, {"CL_RPTPERIOD", CL_RPTPERIOD},
    {"CL_RPTSTATUS", CL_RPTSTATUS}, {"CL_RPTDELAY", CL_RPTDELAY},
    {"CL_RPTAPPR", CL_RPTAPPR}, {"CL_RPTCXL", CL_RPTCXL},
    {"CL_SLASET", CL_SLASET}, {"CL_SLABREACH", CL_SLABREACH},
    {"CL_SCHEDNEXT", CL_SCHEDNEXT}, {"CL_DUELIST", CL_DUELIST},
    {"CL_HOLICHK", CL_HOLICHK}, {"CL_NEXTBIZ", CL_NEXTBIZ},
    {"CL_TRIGSETTLE", CL_TRIGSETTLE}, {"CL_TRIGRPT", CL_TRIGRPT},
    {"CL_STCHGAUDIT", CL_STCHGAUDIT}, {"CL_SNAPMER", CL_SNAPMER},
    {NULL, NULL}
};

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

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

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