/**
 * @file   SCFCBBFC.c
 * @brief  Sample program to copy files with a C++ stream interface
 * @author limes datentechnik gmbh
 ******************************************************************************/

// defines code page for literals for IBM mainframes to German
#ifdef __ZOS__
#  pragma convert(1141)
extern "C" {
#  include <stdlib.h>
}
#endif

#include <istream>
#include <iostream>
#include <string>
#include <cstring>

#if defined(__BORLANDC__)
	#include <stdio.h>
#else
	#include <cstdio>
#endif

#ifdef __ZOS__
#  include "FLCBYTBF.hpp"
#  include "FLMEXCPT.hpp"
#else
#  include "FLCBYTBF.hpp"
#  include "FLMEXCPT.hpp"
#endif

void readOnly(int argc, char **argv) {
   flcbyt_buffer buf(argv[1], argv[2]);
   std::istream in(&buf);

   char strBuf[1025];

   while(in) {
      in.read(strBuf, 1024);
      strBuf[in.gcount()]=0x0;

      std::cout << "echo: " << strBuf << std::endl;
   }
}

void readWrite(int argc, char **argv) {
   flcbyt_buffer rbuf(argv[1], argv[2]);
   flcbyt_buffer wbuf(argv[3], argv[4]);
   std::istream in(&rbuf);
   std::ostream out(&wbuf);
   int count=0;

   char strBuf[1024];

   while(in) {
      in.read(strBuf, 1024);
      count+=in.gcount();
      if (!in.eof() && in.fail()) {
         std::cout << "read failed (eof: "<< in.eof() <<", bytes read so far: " << count << ")" << std::endl;
         std::cout << "error trace:" << std::endl << rbuf.errortrace()  << std::endl;
         break;
      }
      out.write(strBuf, in.gcount());
      if (out.fail()) {
         std::cout << "write failed" << std::endl;
         std::cout << "error trace:" << std::endl << wbuf.errortrace()  << std::endl;
         break;
      }
   }
   std::cout << wbuf.close() << std::endl;
   //out.flush();
}

int main(int argc, char **argv) {

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

#ifdef __ZOS__
   char* a[5]; int i; char* h;
   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;
   }
#endif
   if (argc==2) {
      if (std::strcmp(argv[1],"help")==0) {
         std::cout << flcbyt_buffer::help(FLC_STATE, 10, "") << std::endl;
      } else if (std::strcmp(argv[1],"syntax")==0) {
         std::cout << flcbyt_buffer::syntax(FLC_STATE, 10, "") << std::endl;
      }
   } else if (argc==3) {
      try {
         readOnly(argc, argv);
      } catch (flam_exception& e) {
         std::cout << "FLAM error: " << e.what() << std::endl;
         return 2;
      }
   } else if (argc==5) {
      try {
         readWrite(argc, argv);
      } catch (flam_exception& e) {
         std::cout << "FLAM error: " << e.what() << std::endl;
         return 2;
      }
   } else {
		std::cerr << "Missing file string and/or format string parameter(s)" << std::endl;
		std::cerr << "Usage: " << argv[0] << " <file string> <format string> (reads from byte interface and writes to stdout)" << std::endl;
      std::cerr << "       " << argv[0] << " <file string> <format string> <file string> <format string> (reads and writes via byte interface)" << std::endl;
#ifdef __ZOS__
      std::cerr << "       " << argv[0] << " <file string>,<format string> (reads from byte interface and writes to stdout)" << std::endl;
      std::cerr << "       " << argv[0] << " <file string>,<format string>,<file string>,<format string> (reads and writes via byte interface)" << std::endl;
#endif
		return 1;
	}
	return 0;
}
