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

if ( $#ARGV > 1 || $#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/getinfobypos.pl $POS dcs`;     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;

@table_slv_to_pos = (
     "1:16 1:11 1:15 1:14 1:13 1:12 1:09 1:10 1:08 1:04 1:00 1:01 1:02 1:03 1:07 1:06 1:05 0:11 0:15 0:14 0:13 0:12 0:09 0:10 0:08 0:04 0:00 0:01 0:02 0:03 0:07 0:06 0:05 0:16 9:99 9:99",
     "3:16 3:11 3:15 3:14 3:13 3:12 3:09 3:10 3:08 3:04 3:00 3:01 3:02 3:03 3:07 3:06 3:05 2:11 2:15 2:14 2:13 2:12 2:09 2:10 2:08 2:04 2:00 2:01 2:02 2:03 2:07 2:06 2:05 2:16 9:99 9:99",
     "5:17 5:16 5:11 5:15 5:14 5:13 5:12 5:09 5:10 5:08 5:04 5:00 5:01 5:02 5:03 5:07 5:06 5:05 4:11 4:15 4:14 4:13 4:12 4:09 4:10 4:08 4:04 4:00 4:01 4:02 4:03 4:07 4:06 4:05 4:17 4:16",
     "7:16 7:11 7:15 7:14 7:13 7:12 7:09 7:10 7:08 7:04 7:00 7:01 7:02 7:03 7:07 7:06 7:05 8:11 8:15 8:14 8:13 8:12 8:09 8:10 8:08 8:04 8:00 8:01 8:02 8:03 8:07 8:06 8:05 8:16 9:99 9:99"
);

#
# NI State Machine Table
#

@table_nifsm = (
		"clear",	"idle",		"idle_tr",	"idle_rr",	"idle_net",
		"trk_cpu0",	"trk_cpu0",	"trk_cpu1",	"trk_cpu1",
		"trk_cpu2",	"trk_cpu2",	"trk_cpu3",	"trk_cpu3",
		"trk_port0",	"trk_port1",	"trk_port2",	"trk_port3",
		"raw_cpu0",	"raw_cpu1",	"raw_cpu2",	"raw_cpu3",
		"raw_port0",	"raw_port1",	"raw_port2",	"raw_port3",
		"finished",	"send_test",	"send_test"
);

# make table to convert from slave/lp to irob/imcm
for( $lp = 0 ; $lp < $N_Linkpair ; $lp++ ) {
    @x = split( / /, $table_slv_to_pos[$lp]);
    for( $slave = 1 ; $slave <= 36 ; $slave++ ) {
	($iROB, $iMCM) = split( /:/, $x[$slave-1] );
	@table_rob[$slave."-".$lp] = $iROB;
	@table_mcm[$slave."-".$lp] = $iMCM;
	# printf(" $lp $slave $iROB $iMCM\n");
    }
}

printf("Checking $DCS_ID $ROC_NAME (%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/ROC_Test/rstate.dat |");
    $nslaves      = 0;
    $nslaves_ec   = 0;
    $nslaves_nfsm = 0;
    while(<FILE>) {
	if( /^0x9\s0xa04\s\S+\s(\d+)\s+.+\s+(\S+)\s*$/ ) {  ## TRAP status
	    ($slave, $state) = ($1, $2);
	    ($iROB, $iMCM) = ($table_rob[$slave."-".$lp], $table_mcm[$slave."-".$lp]);
	    $states{$iROB."-".$iMCM} = $state;
	    $nslaves++;
	}
	if( /^0x9\s+0xc04\s+0x(\S+)\s+(\d+)\s+/ ) { ## Event counter 
	    ($slave, $state) = ($2, $1);
	    ($iROB, $iMCM) = ($table_rob[$slave."-".$lp], $table_mcm[$slave."-".$lp]);
	    $evcs{$iROB."-".$iMCM} = $state;
	    $nslaves_ec++;
	}
	if( /^0x9\s+0xdc2\s+0x(\S+)\s+(\d+)\s+/ ) { ## NI state machine
	    ($slave, $state) = ($2, $1);
	    ($iROB, $iMCM) = ($table_rob[$slave."-".$lp], $table_mcm[$slave."-".$lp]);
	    $nfsm{$iROB."-".$iMCM} = $table_nism[hex($state)];
	    $nslaves_nfsm++;
	}
    }
    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

printf("       Linkpair0              Linkpair1              Linkpair2              Linkpair3\n");
printf("Slave   GSM       NI  events   GSM       NI  events  GSM        NI  events   GSM       NI  events\n");

for( $iROB = 0 ; $iROB < $N_Linkpair*2 ; $iROB++ ) {
    printf("ROB %02d\n", $iROB);
    for( $iMCM = 1 ; $iMCM <= 18 ; $iMCM++ ) {
	$Xstate = $states{$iROB."-".$iMCM};
	$Xnfsm  = $nfsm{$iROB."-".$iMCM};
	$Xevcs  = $evcs{$iROB."-".$iMCM};
	printf(" %9s % 4s % 6s", $Xstate,  $Xnfsm, $Xevcs );
	if( defined( $Xstate ) ) {
	    if( ( $Xstate ne "wait_pre" ) || ( $Xevcs ne $Xevc_ref ) ) {
		$flag_bad += 10;
		printf("*");
	    } else {
		printf(" ");
	    }
	} else {
	    printf(" ");
	}
	if( $iMCM % 4 == 3 ) { printf("\n"); }
    }
    printf("\n");
}

# Show Summary

if( $flag_bad > 0 ) {
    printf("Result looks NOT OK...");
    if( $flag_bad >= 10 ) {
	printf("There are non \"wait_pre\" chips or discrepancies in event counters.\n");
    } else {
	printf("See log detail.\n");
    }
} else {
    $evc_ref =~ s/^0x//;
    printf("Result looks OK. All chips processed %s events.\n", hex($evc_ref)-10 );
}

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

# EOF
