/**
 * @file   SCFCRCPX.c
 * @brief  Sample program in C to copy files via the FLUC LE-less
 *         record interface
 * @author limes datentechnik gmbh
 **********************************************************************/

/* defines code page for literals for IBM mainframes to German */
#ifdef __ZOS__
#  pragma convert(1141)
#endif

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdarg.h>
#include<time.h>

#include "FLMRTC.h"
#include "FLCRECXB.h"

#define FCR_DEBUG 1 /* 0 nothing / 1 + opncls / 2 + run + wto-opncls / 3 + wto-run + trace*/

static inline const char *cstime(void) {
   static char    acBuf[20];
   struct tm      st;
   time_t         h=time(NULL);
   struct tm*     x=localtime_r(&h,&st);
   if (x!=NULL) {
      strftime(acBuf,sizeof(acBuf),"%Y-%m-%d %H:%M:%S",x);
   } else {
      snprintf(acBuf,sizeof(acBuf),"NO-VALID-TIME-FOUND");
   }
   return(acBuf);
}
static inline void vdLog(const char *format, ...){
   va_list args;
   char    temp[4096];
   va_start(args,format);
   vsnprintf(temp,sizeof(temp),format,args);
   va_end(args);
   temp[sizeof(temp)-1]=0x00;
   fprintf(stderr,"SCFCRCPX: %s: %s\n",cstime(),temp);
}

/**
 * This test program takes four parameters to convert files via the
 * FLUC record interface.
 *
 * @param  argc must be 5
 * @param  argv contains the strings for FCROPN
 * @return 8=parameter error
 *         6=open file error
 *         4=read write error
 *         2=close error
 *         0=Success
 */
int main(int argc, char * argv[])
{
   void*                   pvRed;
   void*                   pvWrt;
   TsTrc                   stTrc;
   char                    acBuf[65536];
   char                    acSta[2048];
   int                     siLn1=0,siLn2=0,siLen,siSta,siRtc,i;
   int                     siGod=1;
   char*                   h;
   char*                   a[5]={"","","","",""};
   const char*             pcFil=NULL;
   const char*             pcFmt=NULL;
   time_t                  t;

/* defines environment variable LANG to German EBCDIC for IBM mainframes */
#ifdef __ZOS__
   __setenv("LANG","de_DE.IBM-1141",1);
#endif

   if (FCR_DEBUG>0) vdLog("Main started");

   if (argc==2) { /* parse HOST parameter string */
      i=2; a[0]=argv[0]; a[1]=argv[1];
      h=strchr(a[1],',');
      if (h!=NULL) { h[0]=0x00; a[2]=h+1; i++; }
      h=strchr(a[2],',');
      if (h!=NULL) { h[0]=0x00; a[3]=h+1; i++; }
      h=strchr(a[3],',');
      if (h!=NULL) { h[0]=0x00; a[4]=h+1; i++; }
      argc=i; argv=a;
   }

   if (argc!=5) {  exit(1);  }
   if (FCR_DEBUG>0) {
      for (i=0;i<argc;i++) {
         vdLog("Parameter %d(%s)",i+1,argv[i]);
      }
   }

   char string[strlen(argv[1])+strlen(argv[2])+32];
   strcpy(string,"     ");
   strcat(string,argv[2]);
   strcat(string,"     ");
   strcat(string,argv[1]);
   strcat(string,"     ");
   int strLen=strlen(string);

   if (FCR_DEBUG>0) vdLog("Vor ClpCheck(%s)",string);
   siRtc=FCR_DEBUG;/*activate debug level*/
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   CLPCHKX(&siRtc,&stTrc,&strLen,string,&siLn1,&pcFil,&siLn2,&pcFmt);
   if (FCR_DEBUG>0) vdLog("Nach ClpCheck(%s)",string);
   if (siRtc) {
      if (FCR_DEBUG>0) vdLog("Nach ClpCheck failed siRtc=%d\n%s",siRtc,stTrc.acMsg);
      exit(2);
   }

   if (FCR_DEBUG>0) {
      vdLog("ClpChk-File=%d(%.*s)",siLn1,siLn1,(pcFil)?pcFil:"(null)");
      vdLog("ClpChk-Format=%d(%.*s)",siLn2,siLn2,(pcFmt)?pcFmt:"(null)");
   }

   t=time(NULL);

   siSta=sizeof(acSta);
   if (FCR_DEBUG>0) vdLog("Vor Open read");
   siRtc=FCR_DEBUG;/*activate debug level*/
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   FCROPNX(&pvRed,&siRtc,&stTrc,&siLn1,pcFil,&siLn2,pcFmt,&siSta,acSta);
   if (FCR_DEBUG>0) vdLog("Nach Open read");
   if (pvRed==NULL || siRtc) {
      if (FCR_DEBUG>0) vdLog("Nach Open read failed siRtc=%d\n%s",siRtc,stTrc.acMsg);
      exit(3);
   }

   siLn1=strlen(argv[3]); siLn2=strlen(argv[4]);
   if (FCR_DEBUG>0) vdLog("Vor Open write");
   siRtc=FCR_DEBUG;/*activate debug level 1*/
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   FCROPNX(&pvWrt,&siRtc,&stTrc,&siLn1,argv[3],&siLn2,argv[4],&siSta,acSta);
   if (FCR_DEBUG>0) vdLog("Nach Open write");
   if (pvWrt==NULL || siRtc) {
      if (FCR_DEBUG>0) vdLog("Open write failed siRtc=%d, vor close pvRedp\n%s",siRtc,stTrc.acMsg);
      FCRCLSX(&pvRed,NULL,NULL,NULL,NULL,NULL,NULL);
      if (FCR_DEBUG>0) vdLog("Nach close of pvRed in error case at open write");
      exit(4);
   }
   if (FCR_DEBUG>0) vdLog("Vor GET");
   siLen=sizeof(acBuf);
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   FCRGETX(&pvRed,&siRtc,&stTrc,&siLen,acBuf);
   if (FCR_DEBUG>0) vdLog("Nach GET (start loop)");
   while( siRtc==0 ) {
      if (FCR_DEBUG>1) vdLog("Vor PUT");
      stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
      FCRPUTX(&pvWrt,&siRtc,&stTrc,&siLen,acBuf);
      if (FCR_DEBUG>1) vdLog("Nach PUT");
      if (siRtc) {
         if (FCR_DEBUG>0) vdLog("PUT failed siRtc=%d, vor close pvRed and pvWrt\n%s",siRtc,stTrc.acMsg);
         FCRCLSX(&pvRed,NULL,NULL,NULL,NULL,NULL,NULL);
         if (FCR_DEBUG>0) vdLog("Nach close of pvRed in error case at put");
         FCRCLSX(&pvWrt,NULL,NULL,NULL,NULL,NULL,NULL);
         if (FCR_DEBUG>0) vdLog("Nach close of pvwrt in error case at put");
         exit(5);
      }
      if (FCR_DEBUG>1) vdLog("Vor GET");
      siLen=sizeof(acBuf);
      stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
      FCRGETX(&pvRed,&siRtc,&stTrc,&siLen,acBuf);
      if (FCR_DEBUG>1) vdLog("Nach GET");
   }

   if (siRtc!=FLMRTC_OK && siRtc!=FLMRTC_EOF) {
      if (FCR_DEBUG>0) vdLog("GET failed siRtc=%d, vor close pvRed and pvWrt\n%s",siRtc,stTrc.acMsg);
      FCRCLSX(&pvRed,NULL,NULL,NULL,NULL,NULL,NULL);
      if (FCR_DEBUG>0) vdLog("Nach close of pvRed in error case at get");
      FCRCLSX(&pvWrt,NULL,NULL,NULL,NULL,NULL,NULL);
      if (FCR_DEBUG>0) vdLog("Nach close of pvwrt in error case at get");
      exit(6);
   }

   if (FCR_DEBUG>0) vdLog("Vor CLOSE write");
   siLen=sizeof(acBuf);
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   FCRCLSX(&pvWrt,&siRtc,&stTrc,&siGod,NULL,&siLen,acBuf);
   if (FCR_DEBUG>0) vdLog("Nach CLOSE write(%.*s)",siLen,acBuf);
   if (siRtc) {
      if (FCR_DEBUG>0) vdLog("CLOSE write failed siRtc=%d, vor close pvRed\n%s",siRtc,stTrc.acMsg);
      FCRCLSX(&pvRed,NULL,NULL,NULL,NULL,NULL,NULL);
      if (FCR_DEBUG>0) vdLog("Nach close of pvRed in error case at close write");
      exit(7);
   }

   if (FCR_DEBUG>0) vdLog("Vor CLOSE read");
   siLen=sizeof(acBuf);
   stTrc.uiLen=sizeof(stTrc.acMsg); stTrc.acMsg[0]=0x00;
   FCRCLSX(&pvRed,&siRtc,&stTrc,&siGod,NULL,&siLen,acBuf);
   if (FCR_DEBUG>0) vdLog("Nach CLOSE read\n%.*s",siLen,acBuf);
   if (siRtc) {
      if (FCR_DEBUG>0) vdLog("CLOSE read failed siRtc=%d\n%s",siRtc,stTrc.acMsg);
      exit(8);
   }

   vdLog("=== Time Summary (%d)",(int)(time(NULL)-t));

   exit(0);
}

/**********************************************************************/
