#!/usr/local/bin/tclsh

set CTMignoreCVS 0
set CTMapply 1
set CTMdont {^///}

source $argv

cd /u1/CTM/SW

set tmp $CTMtmp
set dd  $CTMdest
set d1  $CTMcopy
set d2  $CTMref
set foo $CTMdate
set foo $CTMprefix
set foo $CTMname

exec sh -x -c "rm -f ${tmp}.*" >&@ stdout

set f1 [open "| ./ctm_scan $d1"]
set f2 [open "| ./ctm_scan $d2"]

set fo_del   [open $tmp.del w]
set fo_rmdir [open $tmp.rmdir w]
set fo_mkdir [open $tmp.mkdir w]
set fo_files [open $tmp.files w]
set changes 0

####
# Find CTM#
for {set i 0} {1} {incr i} {
    if {[file exists [format "%s/$CTMname.%04d" $dd $i]]} continue
    if {[file exists [format "%s/$CTMname.%04d.gz" $dd $i]]} continue
    break
}
set CTMnbr $i

puts "Doing CTMname $CTMname CTMnbr $CTMnbr CTMdate $CTMdate"

#####
# Type Name Mode User Group Barf Size Hash

proc CTMadd {t n m u g b s h} {
    global fo_files fo_mkdir changes d2
    puts stderr "A $b  $t  $n"
    if {$t == "d"} {
	puts $fo_mkdir "CTMDM $n $u $g $m"
	incr changes
	return
    }
    puts $fo_files "CTMFM $n $u $g $m $h $s"
    flush $fo_files
    exec cat $d2/$n >@ $fo_files
    puts $fo_files ""
    incr changes
    return
}
proc CTMdel {t n m u g b s h} {
    global fo_del fo_rmdir changes
    puts stderr "D $b  $t  $n"
    if {$t == "d"} {
	puts $fo_rmdir "CTMDR $n"
	incr changes
	return
    }
    puts $fo_del "CTMFR $n $h"
    incr changes
    return
}
proc CTMchg {t1 n1 m1 u1 g1 b1 s1 h1 t2 n2 m2 u2 g2 b2 s2 h2} {
    global fo_files d2 d1 changes
    if {$t1 == "d" && $t2 == "d"} {
	return
    }
    if {$t1 == "d" || $t2 == "d"} {
	CTMdel $t1 $n1 $m1 $u1 $g1 $b1 $s1 $h1
	CTMadd $t2 $n2 $m2 $u2 $g2 $b2 $s2 $h2
	return
    }
    if {"x$h1" == "x$h2" && $s1 == $s2} {
	return
        puts stderr "M $b1$b2 $t1$t2 $n1"
	puts $fo_files "CTMFA $n2 $u2 $g2 $m2 $h2"
	incr changes
	return
    }
    if {$b1 == "0" && $b2 == "0"} {
	set i [catch "exec diff -n $d1/$n1 $d2/$n2 > tmp" j]
	set s [file size tmp]
	if {$s < $s2} {
	    puts stderr "E $b1$b2 $t1$t2 $n1"
	    puts $fo_files "CTMFN $n1 $u2 $g2 $m2 $h1 $h2 $s"
	    flush $fo_files
	    exec cat tmp >@ $fo_files
	    puts $fo_files ""
	    incr changes
	    return
	}
    }
    puts stderr "R $b1$b2 $t1$t2 $n1"
    puts $fo_files "CTMFS $n2 $u2 $g2 $m2 $h1 $h2 $s2"
    flush $fo_files
    exec cat $d2/$n2 >@ $fo_files
    puts $fo_files ""
    incr changes
    return
}
#####
set l1 ""
set l2 ""

while 1 {

    if {$l1 == ""} {gets $f1 l1}

    if {$l2 == ""} {gets $f2 l2}
    
    if {$l1 == "" && $l2 == ""} break

    set n1 [lindex $l1 1]
    set n2 [lindex $l2 1]

    #if {[regexp $CTMdont /$n1]} { set l1 "" ; continue }
    if {[regexp $CTMdont /$n2]} { set l2 "" ; continue }

    if {$l1 == $l2}  { set l1 "" ; set l2 "" ; continue }

    if {$CTMignoreCVS } {
	if {[regexp {/CVS/} $l1]} {set l1 ""; continue }
	if {[regexp {/CVS/} $l2]} {set l2 ""; continue }
    }

    if {$l1 == "" }   { eval CTMadd $l2 ; set l2 "" ; continue }

    if {$l2 == "" }   { eval CTMdel $l1 ; set l1 "" ; continue }

    if {$n1 < $n2 }   { eval CTMdel $l1 ; set l1 "" ; continue }
    
    if {$n1 > $n2 }   { eval CTMadd $l2 ; set l2 "" ; continue }

    if {$n1 == $n2}  { eval CTMchg $l1 $l2 ; set l1 "" ; set l2 "" ; continue }
}

close $fo_del
close $fo_rmdir
close $fo_mkdir
close $fo_files

exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $tmp.begin
exec echo -n "CTM_END " >> $tmp.end
set m [exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | /sbin/md5]
exec echo "$m" >> $tmp.end

if {!$changes} {
    puts "no changes"
    exec sh -c "rm -f ${tmp}.*"
    exit 0
}
flush stdout
set  nm [format "%s.%04d" $CTMname $CTMnbr]

exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end \
	| gzip -9 > ${tmp}:${nm}.gz 

exec sh -x -c "rm -f ${tmp}.*" >&@ stdout

if {$CTMapply} {
	exec sh -e -x -c "cd $CTMcopy ; /u1/CTM/SW/ctm -v -v -v ${tmp}:${nm}.gz" >&@ stdout
}
exec mv ${tmp}:${nm}.gz $dd/.tmp_${nm}.gz >&@ stdout
exec mv $dd/.tmp_${nm}.gz $dd/${nm}.gz >&@ stdout
