#!/usr/bin/perl
use Getopt::Long;

# misc variables
my (@output, @checks, $file, %controllers);
my $sas2ircu = '/usr/local/sbin/sas2ircu';

# parameters
my @checks = @ARGV;

# check @checks and extract values
process_checks(@checks);

# check command works properly
check_command($sas2ircu . ' list');



# run command
foreach (`$sas2ircu list`)
{
    #   0     SAS2008     1000h    72h   00h:03h:00h:00h      1028h   1f1dh
    if ( /^\s*(\d+)\s+.+\s+.+\s+.+\s+.+\s+.+\s+.+\s*$/ ) { $found{$1} = {}; }
}

foreach $c (keys(%found))
{
    foreach (`$sas2ircu $c display`)
    {
         #        IR Volume information
         #------------------------------------------------------------------------
         #IR volume 1
         #  Volume ID                               : 79
         #  Status of volume                        : Okay (OKY)
         #  RAID level                              : RAID1
         #  Size (in MB)                            : 953344
         #  Physical hard disks                     :
         #  PHY[0] Enclosure#/Slot#                 : 1:0
         #  PHY[1] Enclosure#/Slot#                 : 1:1
        if ( /^\s*IR Volume information\s*$/ ) { $mode = 'IR'; $ir = -1; }
        if ( /^\s*Volume ID\s+:\s+(\d+)\s*/ && $mode eq 'IR' ) { $ir = $1; }
        if ( /^\s*Status of volume\s+:\s+.+\s+\((.+)\)\s*$/ && $mode eq 'IR' && $ir != -1 ) { $found{$c}{'ir'}{$ir} = $1; }


         #Physical device information
         #------------------------------------------------------------------------
         #Initiator at ID #0
         #
         #Device is a Hard disk
         #  Enclosure #                             : 1
         #  Slot #                                  : 0
         #  State                                   : Optimal (OPT)
         #  Size (in MB)/(in sectors)               : 953869/1953525167
         #  Manufacturer                            : ATA
         #  Model Number                            : ST31000524NS
         #  Firmware Revision                       : SN11
         #  Serial No                               : 9WK1EP64
         #  Protocol                                : SATA
         #  Drive Type                              : SATA_HDD

        if ( /^\s*Physical device information\s*$/ ) { $mode = 'PD'; $e = -1; $s = -1; $state = ''; }
        if ( /^\s*Enclosure #\s+:\s+(\d+)\s*$/ && $mode eq 'PD' ) { $e = $1; }
        if ( /^\s*Slot #\s+:\s+(\d+)\s*$/ && $mode eq 'PD' ) { $s = $1; }
        if ( /^\s*State\s+:\s+.+\s+\((.+)\)\s*$/ && $mode eq 'PD' ) { $state = $1; }
        if ( /^\s*Drive Type\s+:\s+(SATA_HDD|SAS_HDD|SATA_SSD|SAS_SSD)\s*$/ && $mode eq 'PD' && $e != -1 && $s != -1 ) { $found{$c}{'enclosures'}{$e}{'slots'}{$s} = $state; }
    }
}


# check found against requested
foreach $c (keys(%found))
{
    foreach $ir (keys(%{$found{$c}{'ir'}}))
    {
        # check IR has a valid status
        if ( $found{$c}{'ir'}{$ir} =~ /^(DGD|FLD|MIS|INIT)$/ ) { print STDERR 'IR #' . $ir . ' is in status: ' . $found{$c}{'ir'}{$ir} . "\n"; failraid(); }
    }

    foreach $e (keys(%{$found{$c}{'enclosures'}}))
    {
        foreach $s (keys(%{$found{$c}{'enclosures'}{$e}{'slots'}}))
        {
            # check slot was requested
            if ( ! exists $requested{$c}{'enclosures'}{$e}{'slots'}{$s} )
            {
                print STDERR 'Controller #' . $c. ', Enclosure #' . $e . ', Slot #' . $s . ' exists but was not requested ( add \'c' . $c . ':e' . $e . ':s' . $s . '\' )' . "\n"; failraid(); }

            # check slot has a valid state
            if ( $found{$c}{'enclosures'}{$e}{'slots'}{$s} =~ /(FLD|MIS|OSY|DGD)/ )
            {
                print STDERR 'Controller #' . $c. ', Enclosure #' . $e . ', Slot #' . $s . ' has status ' . $found{$c}{'enclosures'}{$e}{'slots'}{$s} . "\n";
                failraid();
            }
        }
    }
}

# check requested against found
foreach $c (keys(%requested))
{
    foreach $e (keys(%{$requested{$c}{'enclosures'}}))
    {
        foreach $s (keys(%{$requested{$c}{'enclosures'}{$e}{'slots'}}))
        {
            if ( ! exists $found{$c}{'enclosures'}{$e}{'slots'}{$s} )
            {
                print STDERR 'Controller #' . $c. ', Enclosure #' . $e . ', Slot #' . $s . ' was requested but was not found ( delete \'c' . $c . ':e' . $e . ':s' . $s . '\' )' . "\n";
                failraid();
            }
        }
    }
}


# if we are here, all is ok
okraid();






sub check_command
{
    my ($cmd) = @_;

    # check if the command is valid
    if ( system($cmd . ' > /dev/null') != 0 )
    {
        print STDERR $cmd . ' has failed' . "\n";
        failraid();
    }
}


sub process_checks
{
    my $p;
    foreach (@_)
    {
        if ( /^c(\d+):e(\d+):s(\d+)$/ ) { $requested{$1}{'enclosures'}{$2}{'slots'}{$3} = 0; }
        else
        {
            print STDERR 'Invalid syntax for parameter (' . $_ . '), examples of valid values: "c0:e1:s1" "c1:e2:s7" "c0:e1:s4"' . "\n";
            failraid();
        }
    }
}


sub okraid
{
    print 'RAIDOK';
    exit(0);
}

sub failraid
{
    print 'FAIL';
    exit(0);
}
