#!/mod/bin/jimsh

source /mod/webif/lib/setup
require system.class
require settings.class

proc {system disksmarterror} {sa count ack_count} {
	if {$sa eq "spinretry"} {
		set msg "Disk $sa count is: $count"
	} else {
		set msg "Disk $sa sector count is: $count"
	}
	if {$ack_count > 0} {
		append msg " (was $ack_count)"
	}
	append msg "\n"
	return $msg
}

proc {system disksmart} {} {
	set smartmsg ""

	set smartattrs {realloc pending offline spinretry}

	set smartattribs(SMART_status) "Unknown"
	foreach sa $smartattrs {
		set smartattribs(SMART_$sa) 0
		set smartattribs(SMART_ack_$sa) 0
	}

	foreach line [[settings] smartdata] {
		lassign $line x name x n x t
		if {$name eq "SMART_status"} {
			set smartattribs($name) $t
		} else {
			set smartattribs($name) $n
		}
	}

	# (SMART_ack_status 0 SMART_ack_pending 0 SMART_status PASSED SMART_pending 7 SMART_ack_realloc 0 SMART_ack_offline 0 SMART_realloc 0 SMART_offline 7)

	if {$smartattribs(SMART_status) ne "PASSED" &&
	    $smartattribs(SMART_status) ne "Unknown" &&
	    $smartattribs(SMART_status) ne ""} {
		append smartmsg \
		    "Disk overall health assessment is: $smartattribs(SMART_status)\n"
	}

	foreach sa $smartattrs {
		set count $smartattribs(SMART_$sa)
		set ack_count $smartattribs(SMART_ack_$sa)
		if {$count > $ack_count} {
			append smartmsg [system disksmarterror $sa $count $ack_count]
		} elseif {$count < $ack_count} {
			if {($sa eq "pending" || $sa eq "offline") && ($count > 0)} {
				append smartmsg [system disksmarterror $sa $count $ack_count]
			} else {
				[settings] _nval_setting "SMART_ack_$sa" $count
			}
		}
	}
	return $smartmsg
}

proc {system diskro} {} {
        if {[system model] eq "HDR"} {
		set dev {/mnt/hd[1-3]}
	} else {
		set dev [system diskpart]
	}                                                                       

	# Python re: no POSIX character classes
	# Jim TCL regex: no \x character classes
	# Why not have both ...
	set s {[[:blank:]]}
	set a {[[:alnum:]]}
	set nc {[^,]}
        set roparts [lsearch -all -inline -regexp \
                [split [file read /proc/mounts] "\n\r"] \
		"${s}${dev}${s}+${a}+${s}*(${s}|${nc}+,)ro(,|$|${s})"]
        return [join [lmap line $roparts \
        	{format "Filesystem %s on %s is read-only" [lindex $line 1] [lindex $line 0]}] "\n"]
}

set smartmsg [system disksmart]
set romsg [system diskro]

if {$smartmsg ne "" || $romsg ne ""} {
	if {![dict exists $env SCRIPT_NAME]} { set env(SCRIPT_NAME) "" }
	puts {
<div id=smartwarning class=warningbox style="width: 80%; left: 1%"><center>
!! WARNING !!
<br><br>}
	set problems " "
	if {$smartmsg ne ""} {
		append problems "potential hardware"
	}
	if {$romsg ne ""} {
		if {[string index $problems end] ne " "} {
			append problems " and/or "
		} 
		append problems "filesystem"
	}
	if {[string index $problems end] ne " "} {
		append problems " "
	}
	puts [format "
There are %sproblems with the hard disk on
this system.
<br><br>" $problems]
	if {$smartmsg ne ""} {
		puts "
[string map {"\n" "<br>"} $smartmsg]
<br>
"
	}
	if {$romsg ne ""} {
		puts "
[string map {"\n" "<br>"} $romsg]
<br><br>
"
	}
	if {$env(SCRIPT_NAME) ne "/diag/disk.jim"} {
		puts "
Go to <a href=/diag/disk.jim>Disk Diagnostics</a>
"
	} else {
		puts "
<br>
Don't panic; for help, visit
<a target=_blank href=\"http://wiki.hummy.tv/wiki/Disk_Problem\">wiki.hummy.tv</a>
"
	}
	puts "
</center></div>
"
}

