#!/tvbin/tivosh
# Program to synchronise the channels in the SignalSource with those
# of the underlying Headend. Old channels which are no longer in the
# Headend are removed.
#
# (c) 2006 Warren Toomey, Steve Landers, Martijn van Oosterhout
# GPLv2 license.
#
# $Revision: 1.4 $

tvsource $tcl_library/tv/mfslib.tcl

# Get the channelnumber and station callsign
# of a channel specified by "id/subid"
proc getchannumcall {channel} {
  global db
  lassign [split $channel /] id subid
  RetryTransaction {
    set obj [db $db openidconstruction $id $subid]
    set num [dbobj $obj get Number]
    set station [dbobj $obj get Station]
    if {[lindex [lindex $station 0] 0] == "CONFLICT"} {
      puts "bad lineup station num = $num obj = $station"
      return
    }
    set callsign [dbobj $station get CallSign]
  }
  # puts "num = $num callsign = $callsign station = $station"
  return [list $num $callsign]
}

proc lassign {valueList args} {
  if {[llength $args] == 0} {
    error "wrong # args: lassign list varname ?varname..?"
  }
  uplevel [list foreach $args $valueList {break}]
  return [lrange $valueList [llength $args] end]
}

set db [dbopen]
set yesno [lindex $argv 0]
set foundsome 0

# Open up MFS /Setup and get the available sources
RetryTransaction {
  set setup [db $db open /Setup]
  set sources [dbobj $setup gettarget Source]
}

# For both of the TiVo SignalSources
foreach source $sources {

  # Get the list of channel ids in the SignalSource
  lassign [split $source /] srcid srcsubid
  RetryTransaction {
    set srcobj [db $db openidconstruction $srcid $srcsubid]
    set srcchanlist [dbobj $srcobj gettarget Channel]
    set srcchancnt [llength $srcchanlist]

    # Get the list of channel ids in the Lineup
    lassign [split [dbobj $srcobj gettarget Headend] /] hdid hdsubid
    set headobj [db $db openidconstruction $hdid $hdsubid]
    set lineupid [dbobj $headobj get TmsHeadendId]
    set lineupname [dbobj $headobj get Name]
    set lineupobj [dbobj $headobj get Lineup]
    set linchanlist [dbobj $lineupobj gettarget Channel]
    set linchancnt [llength $linchanlist]
    puts "SignalSource $srcid/$srcsubid: $srcchancnt channels, Lineup $lineupid $lineupname: $linchancnt channels"
  }

  # For every channel in the Lineup, save a record
  # of the number/callsign combination
  foreach channel $linchanlist {
    set numcall [getchannumcall $channel]
    # puts "Lineup Channel $channel is $numcall"
    set lineup($numcall) 1
  }

  # For every channel in the SignalSource,
  foreach channel $srcchanlist {
    # get the number/callsign combination
    set numcall [getchannumcall $channel]
    # puts "Source Channel $channel is $numcall"

    # If the number/callsign combination is not in
    # the lineup, then delete it. Alternatively, if
    # the number/callsign combination is a duplicate,
    # then delete it
    if {![info exists lineup($numcall)] || [info exists duplicate($numcall)]} {
      puts "  delete channel $numcall from SignalSource, not in Lineup"
      set foundsome 1
      if { $yesno == "-y" } {
        RetryTransaction {
          set srcobj [db $db openidconstruction $srcid $srcsubid]
          lassign [split $channel /] id subid
          set chanobj [db $db openidconstruction $id $subid]
          dbobj $chanobj markasrubbish
          dbobj $srcobj remove Channel $chanobj
        }
      }
    } else {
      set duplicate($numcall) 1
    }
  }
  unset lineup
  unset duplicate
}

dbclose $db

if { $yesno != "-y"  && $foundsome == 1 } {
  puts "Rerun this script with the -y argument to do channel deletions"
}

