#!/mod/bin/jimsh

package require cgi
source /mod/webif/lib/setup
require system.class epg.class rsv.class svc.class plugin

set runmode cli
if {[string match {*jim} $argv0]} { set runmode cgi }

set schedtime 1200
switch $runmode {
    cgi {
	set type [cgi_get type "full"]
	httpheader
    }
    cli {
	set type "full"
	if {[lsearch -nocase $argv "-x"] >= 0} { set schedtime 7200 }
    }
}

if {"-d" in $argv} {
	proc debug {arg} { puts $arg }
} else {
	proc debug {arg} {}
}

if {[catch {set pid [exec pgrep -n humaxtv]}]} {
	puts "Cannot find humaxtv process."
	exit
}

set exts {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov .hmt .m4v .m4a}

set statusops {
    decrypt {	"Decrypting"
		"/img/decrypt.png style=\"padding: 0 0.2em 0 0.5em\""
    }
    mpg {	"Extracting MPG"
		"/img/mpg.png style=\"padding: 0 0.2em 0 0.5em\""
    }
    mp {	"Extracting MP3"
		"/img/mp3.png style=\"padding: 0 0.2em 0 0.5em\""
    }
    shrink {	"Shrinking"
		"/img/compress.png style=\"padding: 0 0.2em 0 0.5em\""
    }
    crop {	"Cropping"
		"/img/cut.png style=\"padding: 0 0.2em 0 0.5em\""
    }
    join {	"Joining"
		"/img/cut.png style=\"padding: 0 0.2em 0 0.5em\""
    }
}

proc register_statusop {op name icon} {
	set ::statusops($op) [list $name $icon]
}

eval_plugins status 1

proc get_data {} {
	global pid exts stream tsr tsrcnt

	set ret {}
	if {[catch {set data \
	    [exec /mod/webif/lib/bin/lsof -Fnsa -p $pid]} msg]} {
		debug "Error: $msg"
		set ret {}
	} else {
		set size 0
		foreach line [split $data "\n"] {
			set typ [string index $line 0]
			switch $typ {
			    a {
				set access [string index $line 1]
			    }
			    s {
				set size [string range $line 1 end]
			    }
			    n {
				# strip initial n and trailing " (...)" if
				# present
				regsub -all -- {(^n)|( \([^\)]+\)$)} \
				    $line "" line
				set file [subst -nocommands -novariables $line]
				set ext [file extension $line]
				# Note but skip TSR buffers
				if {[file rootname $file] eq $tsr} {
					if {$ext eq ".nts"} {
						incr tsrcnt
					}
					continue
				}

				if {[string first Video/ $line] >= 0 ||
				    [string first /media/ $line] >= 0} {
					if {$ext ni $exts} {
						continue
					}
				} elseif {[string first $line /] >= 0} {
					# fast skip other files
					continue
				} elseif {[regexp -- {[A-Za-z0-9._-]+:([0-9]+)->([A-Za-z0-9._-]+):([0-9]+)} $line _ sprt host dprt]} {
					if {$sprt == 9000} {
						incr stream
						continue
					} elseif {$dprt == 9000} {
						set file [\
						    format "DLNA from %s" $host]
						set size 0
						set ext ""
					} else {
						continue
					}
				} else {
					continue
				}
				# Handle chase play (same file open twice
				# and recently written)
				if {[dict exists $ret $file] &&
				    $ext eq ".ts"} {
					set age [expr [clock seconds] \
					    - [file mtime $file]]
					if {$age < 60} {
						set access [lindex \
						    [dict get $ret $file] 1]
						set ret($file) [list -1 $access]
					}
				} else {
					debug "$file = $size,$access"
					set ret($file) [list $size $access]
				}
			    }
			}
		}
	}
	foreach file [dict keys $::ops] {
		if {![dict exists $ret $file]} {
			set sz 0
			if {[file exists $file]} { set sz [file size $file] }
			set ret($file) [list $sz u]
		}
	}
	return $ret
}

proc add_output {icon mode name} {
	global runmode output

	if {$runmode eq "cgi"} {
		if {[string first "/" $icon] == -1} {
			set icon "/images/$icon"
		}
		lappend output [concat \
		    "<span class=\"va stitem\">\n" \
		    "  <img class=va src=$icon>\n" \
		    "  <span>$mode&nbsp;<i>$name</i></span>\n" \
		    "</span>\n" \
		    ]
	} else {
		lappend output "$mode $name"
	}
}

set play 0
set rec 0
set stream 0
set output {}
set ops {}
set model [system model]
set tsr [file rootname [system tsr]]
set tsrcnt 0

foreach opfile [glob -nocomplain -directory /tmp -tails -- ".bgop.*"] {
	set op [string range $opfile 6 end]
	lassign [split [file read "/tmp/$opfile"] "\n"] file oppid
	if {$model eq "HDR"} {
		set file [string map {/media/ /mnt/hd2/} $file]
	}

	# Check that the lock is still held
	if {![system checkop $op]} {
		debug "$op - $file - $oppid - process not found."
		file delete "/tmp/$opfile"
	} else {
		set ops($file) $op
	}
}

debug "OPS: $ops"

set data {}
if {$type eq "full"} {
	set data [get_data]
}
if {[llength $data]} {
	debug " DATA: ($data)"
	if {[system nuggeted] && ![file exists /mod/.nonuggetrecs]} {
		set recs [lmap i [split [system nugget recordings] "\n"] {
			function "$i.ts"
		}]
		debug " RECS: $recs"
		set rr 1
	} else {
		sleep 3
		set ndata [get_data]
		debug " NDATA: ($ndata)"
		set rr 0
	}
	set bnames [lsort [lmap x [array names data] { file tail $x }]]
	foreach file [array names data] {
		set bname [file tail $file]

		set name [string map {
			"/mnt/hd2/My Video/" ""
			"/media/drive1/Video/" ""
			"/media/" ""
			".ts" ""
		} $file]

		if {[lindex $data($file) 0] == -1} {
			set mode chase
		} elseif {$rr} {
			if {$file in $recs} {
				set mode rec
			} elseif {[llength [\
			    lsearch -all $bnames $bname]] == 2} {
				# two different files having same file.ext open
				set mode copy
			} else {
				set mode play
			}
		} else {
			if {![dict exists $ndata $file]} continue
			if {[lindex $ndata($file) 0] > \
			    [lindex $data($file) 0]} {
				set mode rec
			} else {
				set mode play
			}
		}

		if {[dict exists $ops $file]} {
			if {$mode eq "rec" || $mode eq "chase"} {
				set mode "Recording"
				set icon "745_1_11_Video_1REC.png"
				add_output $icon $mode $name
			}
			set mode $ops($file)
		}

		regexp -- {^([^0-9]+)} $mode x mode

		switch $mode {
			chase {
				incr rec
				incr play
				set mode "Chase Playing"
				set icon "745_1_11_Video_3REC_Live.png"
			}
			rec {
				incr rec
				set mode "Recording"
				set icon "745_1_11_Video_1REC.png"
			}
			play {
				incr play
				if {$play > $stream} {
					set mode "Playing"
					set icon "745_1_10_Video_2Live.png"
				} else {
					set mode "Streaming"
					set icon "/img/dlna.png"
				}
			}
			copy {
				if {[lindex $data($file) 1] ne "r"} {
					continue
				}
				set mode "Copying"
				set icon "/img/dlna.png"
			}
			default {
				if {[dict exists $statusops $mode]} {
					lassign $statusops($mode) mode icon
				} else {
					set mode "Unknown"
					set icon "/img/blank.gif"
				}
			}
		}

		add_output $icon $mode $name
	}
}

######################################################################
# Live viewing information

if {![system instandby] && $play < 1} {
	set hsvc [system param CUR_SVC Value USERCONFIG]

	set ff [[rsv dbhandle] query "
		select usSvcid as svcid, usLcn as lcn,
		substr(szSvcName, 2) as name
		from channel.TBL_SVC
		where hSvc = $hsvc
		limit 1
	"]

	if {[llength $ff] == 1} {
		lassign [lindex $ff 0] x svcid x lcn x name
		set epgs [epg dbfetch get \
		    -service $svcid \
		    -time [clock seconds]\
		]
		set prog ""
		if {[llength $epgs] == 1} {
			lassign $epgs epg
			set prog "- [$epg get name] ("
			append prog "[clock format [\
			    $epg get start] -format %H:%M] - "
			append prog "[clock format $([$epg get start] \
			    + [$epg get duration]) -format %H:%M]"
			append prog ") \[[$epg percent]%\]"
		}

		# 0 => no TSR; >=2 => TSR
		if {$tsrcnt == 0 || $tsrcnt == 2} {
			set s "Watching"
		} elseif {$tsrcnt == 3} {
			set s "Watching (delayed)"
		} else {
			debug "tsrcnt=$tsrcnt"
			set s "Not watching"
		}
		if {$runmode eq "cgi"} {
			lappend output [format "
			    <span class=\"va stitem\">
			     [epg channelicon %s 30 \
			        {vertical-align: middle; padding: 0 4px 0 2px}]
			    <span>%s <i>%s: %s %s</i></span>
				</span>
			" $name $s $lcn $name $prog]
		} else {
			lappend output [format "%s %s: %s %s" \
			    $s $lcn $name $prog]
		}
	}
}

######################################################################
# In standby

if {[system instandby]} {
	if {$runmode eq "cgi"} {
		lappend output [concat \
		    "<span class=\"va stitem\">\n" \
		    "  <img class=va width=28 style=\"padding: 0 4px\"" \
		    "src=/img/standby.png>\n" \
		    "  <span>System is in standby.</span>\n" \
		    "</span>" \
		]
	} else {
		lappend output "System is in standby."
	}
}

######################################################################
# Upcoming recordings

set events [rsv list tbl_reservation \
    " where ersvtype = 3 and nsttime - [clock seconds] < $schedtime
      and nsttime > [clock seconds] "]
foreach event $events {
	if {$runmode eq "cgi"} {
		set icon "175_1_11_Reservation_Record.png"
		lappend output [concat \
		    "<span class=\"va stitem\">\n" \
		    "  <img class=va src=/images/$icon width=20>\n" \
		    "  <span>Will record <i>[$event name]</i>" \
		    " on [$event channel_name] at"\
		    " [clock format [$event get nsttime] -format {%H:%M}]" \
		    "  </span>\n" \
		    "</span>\n" \
		]
	} else {
		lappend output [concat \
		    "Will record '[$event name]' " \
		    "on [$event channel_name] at " \
		    "[clock format [$event get nsttime] -format {%H:%M}]" \
		]
	}
}

######################################################################
# VFD

if {$runmode ne "cgi" && [file exists /mod/webif/plugin/redring/lib.jim]} {
	source /mod/webif/plugin/redring/lib.jim
	lappend output "VFD: [::redring::vfd]"
}

######################################################################
# Idle Time

if {$runmode ne "cgi"} {
	lappend output "Idle: [clock format [system idletime] -format %T]"
}

######################################################################
# Output

if {[llength $output]} {
	if {$runmode eq "cgi"} {
		puts [join $output "\n<br>\n"]
	} else {
		puts [join $output "\n"]
	}
}

