#! /usr/bin/perl
#
# One argument is necessary. DCS serial and ROC type are taken from _setup

if ( $#ARGV != 0 ) {
    print "\n";
    print "usage: rstate_auto.pl POS\n";
    print "\n";
    print "POS is the chamber position like 1_4_3\n";
    print "\n";
    exit;
}

$POS=$ARGV[0];

$DCS_ID   = `./modules/getdcsbypos.pl $POS`;     chop $DCS_ID;
$ROC_TYPE = `./modules/getinfobypos.pl $POS ctype`;   chop $ROC_TYPE;
$ROC_NAME = `./modules/getinfobypos.pl $POS rocname`;   chop $ROC_NAME;

$N_Linkpair = $ROC_TYPE + 3;
$flag_bad = 0;

printf("Checking status on %d linkpairs.\n\n", $N_Linkpair );

@nslaves_should_be = ( 34, 34, 36, 34 );

for( $lp = 0 ; $lp < $N_Linkpair ; $lp++ ) {
    printf("Getting data from Linkpair $lp ... ");
    open(FILE, "ssh $DCS_ID /usr/local/sbin/dcs2trap -link $lp 0 -i /dcsnfs/SM_Test/rstate.dat 2>&1 | ");
    $nslaves      = 0;
    $nslaves_ec   = 0;
    $nslaves_nfsm = 0;
    while(<FILE>) {
	if ( /ssh:\s\S*\s\S*\s\S*\sdcs(\d+)\s\S*\s22:\S*\s\S*\s\S*\s\S*/ ) {  ## DCS unreachable
	    printf("\n$POS: ERROR. dcs$1 could not be reached.\n");
	    exit;
	}
	if( /^0x9\s0xa04\s\S+\s(\d+)\s+.+\s+(\S+)\s*$/ ) {  ## TRAP status
	    ($slave, $state) = ($1, $2);
	    $states{$slave."-".$lp} = $state;
	    $nslaves++;
	}
	if( /^0x9\s+0xc04\s+0x(\S+)\s+(\d+)\s+/ ) { ## Event counter 
	    ($slave, $state) = ($2, $1);
	    $evcs{$slave."-".$lp} = $state;
	    $nslaves_ec++;
	}
	if( /^0x9\s+0xdc2\s+0x(\S+)\s+(\d+)\s+/ ) { ## NI state machine
	    ($slave, $state) = ($2, $1);
	    $nfsm{$slave."-".$lp} = hex($state);
	    $nslaves_nfsm++;
	}
	if( /^0x9\s+0xb82\s+0x(\S+)\s+(\d+)\s+/ ) { ## NI state machine
	    ($slave, $state) = ($2, $1);
	    $gcntr{$slave."-".$lp} = hex($state);
	    $nslaves_gcntr++;
	}
    }
    printf("% 2d slaves returned data.", $nslaves);
    if( $nslaves != $nslaves_should_be[$lp] ) {
	printf(" ... It is strange!! It should be % 2d.\n",
	       $nslaves_should_be[$lp] );
	$flag_bad++;
    } else {
	printf("\n");
    }
} 
printf("\n");

# Show Results

$evc_ref  = $evcs{"1-0"}; # reference to set to lp0-slv1
$gcntr_ref = $gcntr{"1-0"}; # reference to set to lp0-slv1

printf("     Linkpair 0                     Linkpair 1                     Linkpair 2                     Linkpair 3\n");
printf("Slv  GSM      NI events      ptrg   GSM      NI events      ptrg   GSM      NI events      ptrg   GSM      NI events      ptrg\n");

for( $s = 1 ; $s <= 36 ; $s++ ) {
    printf("%02d ", $s);
    for( $lp = 0 ; $lp < $N_Linkpair ; $lp++ ) {
	printf(" %9s %02s % 6s % 9s", $states{$s."-".$lp}, $nfsm{$s."-".$lp}, $evcs{$s."-".$lp}, $gcntr{$s."-".$lp} );
	if( defined( $states{$s."-".$lp}) ) {
	    if( ($states{$s."-".$lp} ne "wait_pre") || ($evcs{$s."-".$lp} ne $evc_ref)   || ($gcntr{$s."-".$lp} ne $gcntr_ref)   ) {
		$flag_bad += 10;
		printf("*");
	    } else { printf(" "); }
	} else { printf(" "); }
    }
    printf("\n");
}

printf("\n");

# Show Summary

if( $flag_bad > 0 ) {
    printf("$POS: NOT OK... ");
    if( $flag_bad >= 10 ) {
	printf("Non \"wait_pre\" chips or discrepancies in counters.\n");
    } else {
	printf("Check with \"./rstate_auto.pl $POS\" for details.\n");
    }
} else {
    $evc_ref =~ s/^0x//;
    printf("$POS: OK. All chips in \"wait_pre\" mode, EvtCtr=%s GCNTR=%d.\n", hex($evc_ref)-10, $gcntr_ref);
}

printf("\nNow: %s", `date`);

# EOF
