/*===========================================================================
  Copyright (C) 1995-2010 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*

test program for communication via Midas on-line interfaces

K. Banse, 941020, 970219, 981130, 990901, 010425, 050617, 051012

100616		last modif

*/


#include <fileexts.h>

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

#define MAX_MIDAS_LINE 400			/* sync with monitdef.h !! */


/*

*/

int Getline(s,lim)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.KEYWORDS
  terminal
.PURPOSE
  get an input line from the terminal
.ALGORITHM
  use C-function getchar
.RETURNS
  nothing
--------------------------------------------------*/

char s[];        /* OUT: input line from terminal  */
int  lim;        /* IN: max. length of input string  */

{
int  nr;



lim --;
if (lim < 0)
   {
   s[0] = '\0';
   return 0;
   }

for (nr=0; nr<lim; nr++)
   {
   s[nr] = (char) getchar();
   if ( (s[nr] == '\n') || (s[nr] == '\r') )
      {
      s[nr] = '\0';
      return (nr); 
      }
   }

s[lim] = '\0';
return (lim);
}
/*

*/

int main(argc,argv)
int  argc;
char *argv[];
 
{
int        verify, fp, batch, id, stat, n;
int        noelm, retstat[2], jj, iwa[3], ibuf[80];
int        nowait, felem, maxvals, actvals, unit, nullo, kstat;
register int nr;
 
float      rwa[3], rbuf[80];

double     dwa[3], dbuf[80];

char       metho, munit[4], kline[MAX_MIDAS_LINE+4], frame[80];
char       versio[12], *vers, jline[256], cbuf[80];



id = -1;
batch = 0;
verify = 0;
stat = fp = nowait = 0;
metho = '\0';
(void) strcpy(munit,"  ");

if (!(vers = getenv("MIDVERS")))
   (void) strcpy(versio,"x99NOV");			/* no parallel mode */
else
   {
   versio[0] = 'x';
   (void) strcpy(&versio[1],vers);
   }


begin_it:
if (argc > 1)
   {
   if (strncmp(argv[1],"veri",4) == 0)
   (void) strcpy(frame,"MID_MONIT:communi.cmd");
   fp = CGN_OPEN(frame,0);
   if (fp == -1)
      {
      (void) printf("could not open file %s\n",frame);
      ospexit(1);
      }
   (void) strcpy(frame,"communi.cmd");
   verify ++;
   batch = 1;

   if (verify == 1)
      {
      (void) printf(" *** testing socket based communication ***\n");
      (void) strcpy(kline,"is ");
      }
   else
      {
      (void) printf(" *** testing files/interrupts based communication ***\n");
      (void) strcpy(kline,"if ");
      }

   if (argc > 2)
      (void) strcat(kline,argv[2]);
   else
      (void) strcat(kline,"00");

   if (argc > 3)
      versio[0] = CGN_UPPER(*argv[3]);

   (void) printf("%s> %s\n",frame,kline);
   goto parse_input;
   }


input_loop:
if (verify != 0)
   {
   if (stat != 0)
      {
      (void) printf("********************************\n");
      (void) printf("We got a problem in the verification procedure...\n");
      (void) printf("********************************\n");
      ospexit(1);
      }
   }

if (batch == 0)
   {
   if (id == -1)
      {
      (void) printf("Options are:\n");
      (void) printf
      ("os XY = open local socket communication with Midas unit XY\n");
      (void) printf
      ("os host:XY = open network socket communication with Midas unit XY\n");
      (void) printf
      ("of XY = open ASCII file based comm. with Midas unit XY\n");
      (void) printf
      ("is XY = start Midas unit XY + open local socket communication\n");
      (void) printf
     ("is host:XY = start Midas unit XY + open network socket communication\n");
      (void) printf("currently only possible for host = local host\n");
      (void) printf
      ("if XY = start Midas unit XY + open ASCII file based comm.\n");
      (void) printf("h = display help text, q = quit the test program\n");
      }

   (void) printf("option > ");
   (void) Getline(kline,80);
   }

else
   {
   stat = osaread(fp,kline,120);       /* read record from ASCII file */
   if (stat == 0)
      goto input_loop;
   else if (stat < 0)
      {
      osaclose(fp);
      batch = 0;
      if (verify == 1)
         {
         ospwait(3);
         goto begin_it;
         }
      else if (verify > 1)
         {
         (void) printf("********************************\n");
         (void) printf("Verification procedure successfully terminated...\n");
         (void) printf("********************************\n");
         ospexit(0);
         }
      else
         goto input_loop;
      }
   stat = 0;
   if (verify > 1) ospwait(2);
   (void) printf("%s> %s\n",frame,kline);
   }


parse_input:
while (kline[0] == ' ')			/* skip leading blanks */
   CGN_strcpy(kline,&kline[1]);

if (kline[0] == '\0')			/* empty line */
   goto input_loop;

else if (kline[0] == 'q') 
   ospexit(0);

else if (kline[0] == '@')
   {
   if (batch == 1)
      {
      (void) printf("no nesting of batches possible...\n");
      goto input_loop;
      }

   fp = osaopen(&kline[2],0);            /*  means reading only */
   if (fp == -1)
      {
      (void) printf("could not open file %s\n",&kline[2]);
      goto input_loop;
      }

   batch = 1;
   (void) strcpy(frame,&kline[2]);
   goto input_loop;
   }

else if (kline[0] == 'h')
   {
   (void) printf("Options are:\n");
   (void) printf("h = display help text, q = quit the test program\n");
   (void) printf("c `secs' = send Midas command + wait for `secs'\n");
   (void) printf("w = wait for last command, s = get status\n");
   (void) printf
("x = close client connection, xx = as `x' but also terminate Midas server\n");
   (void) printf("XCKRDz keyname,felm,maxval = test XCKRDz commands\n");
   (void) printf("XCKWRz keyname,felm,maxval,value = test XCKWRz commands\n");
   (void) printf("XCKRDC*n keyname,felm,maxval = test XCKRDC commands\n");
   (void) printf
   ("XCKWRC*n keyname,felm,maxval,value = test XCKWRC commands\n");
   (void) printf("@ filename = execute the commands from file `filename'\n");
   }

else if (kline[0] == 'i')
   {
   char   tempy;

   nowait = 0;

   if (kline[1] == 's')			/* sockets */
      {
      metho = 'X';
      n = CGN_INDEXC(&kline[3],':');
      if (n > 0)
         {
         n += 3;
         kline[n++] = '\0';
         tempy = kline[n++];
         munit[0] = CGN_UPPER(tempy);
         munit[1] = CGN_UPPER(kline[n]);	/* use network sockets */
         stat = XCXINI(munit,&kline[3],"",versio,10,&id);
         }
      else
         {
         munit[0] = CGN_UPPER(kline[3]);
         munit[1] = CGN_UPPER(kline[4]);	/* use local sockets */
         stat = XCXINI(munit,"","",versio,10,&id);	/* wait max. 10 sec */
         }
      }
   else					/* files */
      {
      munit[0] = CGN_UPPER(kline[3]);
      munit[1] = CGN_UPPER(kline[4]);
      metho = 'Z';
      stat = XCZINI(munit,"QX","","",versio,10,&id);
      }

   (void) printf("XC%cINI, status = %d, id returned = %d\n",metho,stat,id);
   }

else if (kline[0] == 'o')
   {
   char  tempy;

   nowait = 0;

   if (kline[1] == 's')                 /* sockets */
      {
      metho = 'X';
      n = CGN_INDEXC(&kline[3],':');
      if (n > 0)
         {
         n += 3;
         kline[n++] = '\0';
         tempy = kline[n++];
         munit[0] = CGN_UPPER(tempy);
         munit[1] = CGN_UPPER(kline[n]);	/* use network sockets */
         stat = XCXOPN(munit,&kline[3],&id);
         }
      else
         {
         munit[0] = CGN_UPPER(kline[3]);
         munit[1] = CGN_UPPER(kline[4]);	/* use local sockets */
         stat = XCXOPN(munit,"",&id);
         }
      }
   else                                 /* files */
      {
      munit[0] = CGN_UPPER(kline[3]);
      munit[1] = CGN_UPPER(kline[4]);
      metho = 'Z';
      stat = XCZOPN(munit,"QX","",&id);
      }

   (void) printf("XC%cOPN, status = %d\n",metho,stat);
   }

else if (kline[0] == 'x')
   {
   if (kline[1] == 'x')			/* also shut down server */
      {
      stat = XCXSTP(id);
      (void) printf("XCXSTP, status = %d\n",stat);
      }
   else
      {
      stat = XCXCLO(id);
      (void) printf("XCXCLO, status = %d\n",stat);
      }

   id = -1;
   }

else if (kline[0] == 'c')
   {
   if (kline[1] == ',')			/* c,command_line  */
      {
      iwa[0] = -1;			/* wait forever */
      CGN_strcpy(kline,&kline[2]);
      }
   else
      {
      n = (int) strlen(kline);
      if (n > 2)
         {
         n = CGN_CNVT(&kline[2],1,1,iwa,rwa,dwa);
         if (n<1) iwa[0] = -1;
         }
      else
         iwa[0] = -1;			/* wait forever */

      if (batch == 0)
         {
         (void) printf("Enter Midas command: \n");
         (void) Getline(kline,80);
         if (strcmp(kline,"Klaus") == 0)	/* special test */
            {
            n = CGN_COPY(kline,"write/out aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff gg xx");
            (void) 
            printf("for `Klaus' we send write/out command of length %d\n",n);
            }
         }
      else
         {
         stat = osaread(fp,kline,120);       /* read record from ASCII file */
         if (stat == 0)
            goto input_loop;
         else if (stat < 0)
            {
            osaclose(fp);
            batch = 0;
            goto input_loop;
            }
         (void) printf("%s> %s\n",frame,kline);
         }
      }
   (void) printf("Command sent: %s (%d secs wait)\n",kline,iwa[0]);
   stat = XCCSND(id,kline,iwa[0],retstat);
   if (iwa[0] == 0)
      nowait = 1;
   else
      nowait = 0;

   if (stat != 0)
      {
      if (stat == 1)		/* last command closed connection */
         {
         (void) printf
         ("\nThe command sent via XCCSND closed the connection...\n\n");
         stat = XCXCLO(id);
         id = -1;
         }
      else
         (void) printf("XCCSND, status = %d\n",stat);
      }
   else
      {
      (void) printf("background Midas returned status = %d\n",retstat[0]);
      if (retstat[0] == 56)
         {
         char tmpc[80];
         int  waitcount = 0;

         tmpc[0] = 'c';			/* prepare new command line */
         tmpc[1] = ',';
         (void) strcpy(&tmpc[2],kline);
         (void) strcpy(kline,tmpc);

         if (metho == 'Z')
            {			/* now it's tough to get the data */
            stat = XCCSND(id,"write/out {q3(1:60)} >klaus.q3 ",iwa[0],retstat);
           wait_more:
            fp = osaopen("klaus.q3",0);            /*  means reading only */
            if (fp == -1)
               {
               if (waitcount < 100)
                  {
                  sleep(5);
                  waitcount ++;
                  goto wait_more;
                  }
               else
                  {
                  printf("Problems: could not open file `klaus.q3'\n");
                  goto input_loop;
                  }
               }
            n = osaread(fp,cbuf,60);
            cbuf[n] = '\0';
            (void) osaclose(fp);

            }
         else
            {
            stat = XCKRDC(id,"Q3",1,1,60,&actvals,cbuf,&unit,&nullo,&kstat);
            if (stat != 0) (void) printf(
                   "Problems with XCKRDC of key Q3, status = %d\n",stat);
            else if (kstat != 0) (void) printf(
                   "Problems: background Midas returned status = %d\n",kstat);
            }
 
         printf("parameter %2.2s must be given for last command!\n",cbuf);
         if (cbuf[3] == '"')
            {					/* cut out the quotes */
            (void) strcpy(tmpc,&cbuf[4]);
            n = (int) strlen(tmpc);
            if (n > 0) tmpc[n-1] = '\0';
            }
         else
            (void) strcpy(tmpc,&cbuf[3]);
         printf("%s",tmpc);
         (void) Getline(cbuf,80);
         (void) strcat(kline," ");
         (void) strcat(kline,cbuf);
         goto parse_input;
         }
      }
   }

else if (kline[0] == 'w')
   {
   stat = XCCWAI(id,retstat);

   if (stat != 0)
      (void) printf("XCCWAI, status = %d\n",stat);
   else
      {
      (void) printf("background Midas returned status = %d\n",retstat[0]);
      nowait = 0;
      }
   }

else if (kline[0] == 's')
   {
   stat = XCXSTA(id);

   if (stat == 0)
      (void) printf("background Midas %c%c idle\n",munit[0],munit[1]);
   else if (stat == 1)
      (void) printf("background Midas %c%c busy\n",munit[0],munit[1]);
   else
      (void) printf("XCXSTA, status = %d\n",stat);
   }


/* XCKRDz and XCKWRz tests */

else if (strncmp(kline,"XCK",3) == 0)
   {
   if (verify > 1) 			/* ignore XCKyz calls */
      {
      (void) printf("Not applicable in file based communication\n");
      goto input_loop;
      }

   if (nowait == 1)
      {
      stat = XCCWAI(id,retstat);
      nowait = 0;
      }

   jj = CGN_INDEXC(kline,' ');
   if (jj < 1)
      {
      (void) printf("invalid input...\n");
      goto input_loop;
      }
   strcpy(jline,&kline[++jj]);
   jj = CGN_INDEXC(jline,',');
   if (jj < 1)
      {
      (void) printf("invalid input...\n");
      goto input_loop;
      }
   else
      {
      jline[jj] = '\0';			/* isolate keyword name */
      strcpy(cbuf,&jline[++jj]);
      n = CGN_CNVT(cbuf,1,2,iwa,rwa,dwa);
      if (n<2) 
         {
         (void) printf("invalid input...\n");
         goto input_loop;
         }
      felem = iwa[0];
      maxvals = iwa[1];
      }
      
   if (kline[3] == 'R')		/* read Key calls */
      {
      if (kline[5] == 'I')
         stat = 
         XCKRDI(id,jline,felem,maxvals,&actvals,ibuf,&unit,&nullo,&kstat);
      else if (kline[5] == 'R')
         stat = 
         XCKRDR(id,jline,felem,maxvals,&actvals,rbuf,&unit,&nullo,&kstat);
      else if (kline[5] == 'D')
         stat = 
         XCKRDD(id,jline,felem,maxvals,&actvals,dbuf,&unit,&nullo,&kstat);
      else 
         {
         if (kline[6] == '*')
            {
            jj = CGN_INDEXC(kline,' ');
            kline[jj] = '\0';
            n = CGN_CNVT(&kline[7],1,1,&noelm,rwa,dwa);
            if (n < 1) noelm = 1;
            }
         else
            noelm = 1;
         stat = 
         XCKRDC(id,jline,noelm,felem,maxvals,&actvals,cbuf,&unit,&nullo,&kstat);
         }
  
      if (stat != 0)
         (void) printf("Problems with XCKRDI interface, status = %d\n",stat);
      else
         {
         if (kstat != 0)
            (void) printf("Problems: background Midas returned status = %d\n",
                   kstat);
         else
            {
            if (kline[5] == 'I')
               {
               (void) printf("keyword: %s, 1. element %d, %d values\n",
                      jline,felem,actvals);
               for (nr=0; nr<actvals; nr++)
                  (void) printf("%d\n",ibuf[nr]);
               }
            else if (kline[5] == 'R')
               {
               (void) printf("keyword: %s, 1. element %d, %d values\n",
                      jline,felem,actvals);
               for (nr=0; nr<actvals; nr++)
                  (void) printf("%10.4f\n",rbuf[nr]);
               }
            else if (kline[5] == 'D')
               {
               (void) printf("keyword: %s, 1. element %d, %d values\n",
                      jline,felem,actvals);
               for (nr=0; nr<actvals; nr++)
                  (void) printf("%14.7e\n",dbuf[nr]);
               }
            else
               {
               (void) printf("keyword: %s, 1. element %d, %d values\n",
                      jline,felem,actvals);
               cbuf[actvals] = '\0';
               (void) printf("%s\n",cbuf);
               }
            }
         }
      }
   else
      {
      if (kline[5] == 'I')
         {
         n = CGN_CNVT(cbuf,1,3,iwa,rwa,dwa);
         if (n < 1) iwa[2] = -999;
         for (nr=0; nr<maxvals; nr++)
            ibuf[nr] = iwa[2];
         stat = XCKWRI(id,jline,ibuf,felem,maxvals,&unit,&kstat);
         }
      else if (kline[5] == 'R')
         {
         n = CGN_CNVT(cbuf,2,3,iwa,rwa,dwa);
         if (n < 1) rwa[2] = -999.9;
         for (nr=0; nr<maxvals; nr++)
            rbuf[nr] = rwa[2];
         stat = XCKWRR(id,jline,rbuf,felem,maxvals,&unit,&kstat);
         }
      else if (kline[5] == 'D')
         {
         n = CGN_CNVT(cbuf,4,3,iwa,rwa,dwa);
         if (n < 1) dwa[2] = -999.9;
         for (nr=0; nr<maxvals; nr++)
            dbuf[nr] = dwa[2];
         stat = XCKWRD(id,jline,dbuf,felem,maxvals,&unit,&kstat);
         }
      else
         {
         if (kline[6] == '*')
            {
            jj = CGN_INDEXC(kline,' ');
            kline[jj] = '\0';
            n = CGN_CNVT(&kline[7],1,1,&noelm,rwa,dwa);
            if (n < 1) noelm = 1;
            }
         else
            noelm = 1;

         jj = CGN_INDEXC(cbuf,',');
         CGN_strcpy(cbuf,&cbuf[++jj]);
         jj = CGN_INDEXC(cbuf,',');
         cbuf[0] = cbuf[++jj];
         for (nr=1; nr<maxvals*noelm; nr++)
            cbuf[nr] = cbuf[0];
         stat = XCKWRC(id,jline,noelm,cbuf,felem,maxvals,&unit,&kstat);
         }

      if (stat != 0)
         (void) printf("Problems with XCKRDI interface, status = %d\n",stat);
      else if (kstat != 0)
         (void) printf(
         "Problems: background Midas returned status = %d\n", kstat);
   
      }
   }

else if (kline[0] == '!')		/* comment line */
   goto input_loop;

else
   (void) printf("unknown command...\n");

goto input_loop;		/* get next input */

}

