/***************************************
*  dbase_test.c                        *
*                                      *
***************************************/

#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <strings.h>
#include <modes.h>
#include <module.h>
#include "../lib/mylib1.h"
#include "a200.h"
#include "../dbase/hv_dbase.h"

main(argc, argv)
int argc;
char *argv[];
{
   hv_mod_struct *mid;
   char *mod_name0 = "hv_config0";
   char *mod_name1 = "hv_config1";
   char *mod_name2 = "hv_config2";
   char *mod_name, *hv_config[3]; 
   short i, j, k, chan, value;
   int code, piano, ott1, ott2;
   int dis, sl;
   char *par_code, *crate_code, *chan_code, *set_code, *chamber_code;
   short par_val, crate_val, chan_val, set_val;
   int is_a_cable;
   char *balc_code;
   int cpu_nr, tcp_ip_nr;
   int ch1, ch2, first_print;     /* for used channels */
   int dch1, dch2, dfirst_print;  /* for disconnected channels */
   int n_connected, n_used;
   int ntot_connected, ntot_used;
   int lst = 0;

   if (argc < 2 || *argv[1] =='-'){
      printf(" dbase_test   : to test hv data base\n");
      printf("\n usage     : dbase_test Chamber_name [Balc] [lst]\n");
      printf("            The Chamber_name is interpreted as CABLE_name\n");  
      printf("            if the format XX/Y is used ( e.g. : 52/2 )   \n"); 
      printf("            The chamber name may be 'all'. \n\n"); 
      printf("            Balc can be either Sud/Nord or 1/2.\n"); 
      printf("            If not specified the current Balcony is assumed\n\n"); 
      printf("            'lst' is an optional parameter to check also \n"); 
      printf("            the LST connection. In this case also the Balcony\n"); 
      printf("            must be explicitly indicated\n"); 
      exit(0);
   }

   chamber_code = argv[1];
   if ( strcmp("all", chamber_code) == 0
   || strcmp("ALL", chamber_code) == 0)
      chamber_code = "0";
   
   is_a_cable = 0;
   if (*(chamber_code + 2) == '/')
      is_a_cable = 1;   

   if (argc >= 3){   /* also the balcony is specified */ 
      balc_code = argv[2];
      if (*balc_code == '1' || *balc_code == 's' || *balc_code == 'S'){
         cpu_nr = 1;
         mod_name = mod_name1;
      }
      else if (*balc_code == '2' || *balc_code == 'n' || *balc_code == 'N'){
         cpu_nr = 2;
         mod_name = mod_name2;
      }
      else{
         printf(" bad balcony name ( it can be either SUD/NORD or 1/2 !)\n");  
         exit(0);
      }
   }
   else{    /* take the cpu_nr from the TCP/IP address */
      get_config(&tcp_ip_nr, &cpu_nr, hv_config);
      mod_name = hv_config[cpu_nr];
   }    

   if (argc >= 4){
         upperword(argv[3]);
      if ( strcmp(argv[3], "LST") == 0)
         lst = 1;
   }

   if ((mid = (hv_mod_struct *)modlink(mod_name, 0))
   == (hv_mod_struct *)-1)
      if ((mid = (hv_mod_struct *)modload(mod_name, 0))
      == (hv_mod_struct *)-1)
         exit(_errmsg(errno, "dbase_test.c: error linking module %s\n",
         mod_name));
   
   ntot_connected = ntot_used = 0;
   printf("\n connessions to %s :\n", chamber_code);
   for(dis = 0; dis < mid->n_crates; dis++)
    for(sl = 0; sl < 4; sl++)
     for(k = 0; k < 2; k++)
       if(strcmp(chamber_code, mid->distr[dis].slot[sl].cable[k].chamber) == 0
       || strcmp(chamber_code, mid->distr[dis].slot[sl].cable[k].cable_name)
       == 0 || ( strcmp("0", chamber_code) == 0  &&
       mid->distr[dis].slot[sl].hv_ch >= 0       &&
       mid->distr[dis].slot[sl].cable[k].first_ch >= 0) ){
          printf("    cable %s: d_crate %d, slot %d, hv_ch %d :\n",
          mid->distr[dis].slot[sl].cable[k].cable_name,
          mid->distr[dis].crate_nr , sl, 
          mid->distr[dis].slot[sl].hv_ch);

          n_connected = n_used = 0;
          ch1 = -1;
          first_print = 1;
          /* print lst connections if required */
          if (lst){
             printf("\nSlot_ch  wire#   Status            L S T\n");
             for ( i = 0; i < 32; i++){ 
                printf("  %2d     %2d    ", i, i + 1);
                if (mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ))
                   printf("  OK  ");
                else if ( !(mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ))
                        && (mid->distr[dis].slot[sl].d_conn_ch & ( 1 << i )))
                   printf(" disc ");
                else
                   printf("  --  ");
                code = mid->distr[dis].slot[sl].lst[i][0];
                piano = code / 10000;
                if (piano){
                   printf("      layer %d: ", piano);
                   ott1 = (code - piano * 10000)/100 ;
                   ott2 = ( code - piano * 10000 - ott1 * 100);
                   if (ott1)
                      printf(" %2d, ", ott1);
                   if (ott2)
                      printf(" %2d", ott2);
                   printf(";  ");
                   if (!ott1 || !ott2)
                      printf("     ");  
                }
                code = mid->distr[dis].slot[sl].lst[i][1];
                piano = code / 10000;
                if (piano){
                   printf(" layer %d: ", piano);
                   ott1 = (code - piano * 10000)/100 ;
                   ott2 = ( code - piano * 10000 - ott1 * 100);
                   if (ott1)
                      printf(" %2d, ", ott1);
                   if (ott2)
                      printf(" %2d", ott2);
                   printf(".");
                }          
                printf("\n");
             }
          } 
          for ( i = 0; i < 32; i++){ 
          /* summary of connected channels */
             if (mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ) ) {
                n_used++;
                ch2 = i;
                if ( ch1 < 0 )
                   ch1 = i;
             }
             else if ( !(mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ) ) ){ 
                if ( ch1 >= 0) {
                   if (first_print){
                      printf("  d_ch's used: ");
                      first_print = 0;
                   }
                   else
                      printf(",");
                   if ( ch1 == ch2 )
                      printf(" %d", ch1);
                   else
                      printf(" %d-%d", ch1, ch2);
                   ch1 = -1;
                } 
             }
          }
          if ( ch1 >= 0) {
             if (first_print){
                printf(" d_ch's used: ");
                first_print = 0;
             }
             else
                printf(",");
             if ( ch1 == ch2 )
                printf(" %d", ch1);
             else
                printf(" %d-%d", ch1, ch2);
             ch1 = -1;
          }
          if ( !first_print )
             printf(".\n");  
          /* now analyse disconnected channels */       
          dch1 = -1;
          dfirst_print = 1;
          for ( i = 0; i < 32; i++){ 
             if ( mid->distr[dis].slot[sl].d_conn_ch & ( 1 << i ) )
                n_connected++;
             if ( mid->distr[dis].slot[sl].d_conn_ch & ( 1 << i ) &&
                !(mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ) ) ) {
                dch2 = i;
                if ( dch1 < 0 )
                   dch1 = i;
             }
             else if ( ( (mid->distr[dis].slot[sl].d_conn_ch & ( 1 << i ) ) && 
                      (mid->distr[dis].slot[sl].d_used_ch & ( 1 << i ) ) ) || 
                      !(mid->distr[dis].slot[sl].d_conn_ch & ( 1 << i ) ) ) { 
                if ( dch1 >= 0) {
                   if (dfirst_print){
                      printf(" disconnected : ");
                      dfirst_print = 0;
                   }
                   else
                      printf(",");
                   if ( dch1 == dch2 )
                      printf(" %d", dch1);
                   else
                      printf(" %d-%d", dch1, dch2);
                   dch1 = -1;
                } 
             }
          }
          if ( dch1 >= 0) {
             if (dfirst_print){
                printf(" disconnected: ");
                dfirst_print = 0;
             }
             else
                printf(",");
             if ( dch1 == dch2 )
                printf(" %d", dch1);
             else
                printf(" %d-%d", dch1, dch2);
             dch1 = -1;
          }
          if ( !dfirst_print )
             printf(".\n");
          ntot_connected += n_connected;  
          ntot_used += n_used;  
          printf(" used/conn. ch's %d/%d", n_used, n_connected); 
          printf(" (%.1f %%) \n\n",
          (float) n_used / (float) n_connected * 100.);
       }
       printf("\n\n Summary of used/connected distr. channels %d/%d",
       ntot_used, ntot_connected);
       printf(" (%.1f %%) \n",
       (float) ntot_used / (float) ntot_connected * 100.);
   munlink(mid);
}