#!/bin/sh  
# \
  exec oagtclsh "$0" "$@"



set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
set CVSRevisionAuthor "\$Revision: 1.10 $ \$Author: emery $"

proc loadSnapshotLib {} {
    set libFile /usr/local/oag/bin_patch/solaris/libTclSnapshot.1.3.so
    #    set libFile /home/helios/SOLIDAY/oag/apps/lib/solaris/libTclSnapshot.1.3.so
    if [catch {load $libFile} error] {
        puts stderr "$error"
        exit
    }
}

proc getvalues {requestFile timeOut} {
    #Read request file
    if [catch {snapshot readRequest $requestFile} ControlName] {
        return -code error $ControlName
    }

    #Communicating with PVs
    eval global env $ControlName
    if [catch {snapshot linkPVs $ControlName $timeOut errorTclNameList} error] {
        return -code error $error
    }

    #Attempting to get all the PVs at once
    if [catch {snapshot getPVs $ControlName $timeOut 1 errorTclNameList} error] {
        return -code error $error
    }

    set numErrors [llength $errorTclNameList]
    if {$numErrors} {
        foreach name $errorTclNameList {
            set $name "--Snapshot Error--"
        }
    }

    #Write snapshot file
    set snapshotFile /home/helios/oagData/SCR/swapSpace/[APSTmpString]
    set logFile ${snapshotFile}.log
    set timeInSeconds [clock seconds]

    if [catch {snapshot write $requestFile $snapshotFile \
                 $ControlName \
                 [list LoginID SDDS_STRING $env(USER)] \
                 [list SnapType SDDS_STRING Absolute] \
                 [list TimeStamp SDDS_STRING [clock format $timeInSeconds]] \
                 [list Time SDDS_LONG $timeInSeconds] \
                 [list InputFile SDDS_STRING $requestFile] \
                 [list LogFile SDDS_STRING $logFile]} error] {
        file delete -- $snapshotFile
        return -code error $error
    }
    file attributes $snapshotFile -permissions 0775

    #Write system log
    set log "SDDS1\n&parameter name = Time, type = long, &end\n"
    append log "&column name = ControlName, type = string, &end\n"
    append log "&data mode = ascii, &end\n! page number 1\n$timeInSeconds\n\t$numErrors"
    if {$numErrors} {
        append log \n[join $errorTclNameList \n]
    }
    if [catch {open $logFile w} fileID] {
        file delete -- $snapshotFile
        return -code error $fileID
    }
    puts $fileID $log
    catch {close $fileID}
    file attributes $logFile -permissions 0775

    return -code ok [list $snapshotFile $logFile "$numErrors PVs not connected"]
}

proc setvalues {snapshotFile timeOut} {
    #Read snapshot file
    if [catch {snapshot readSnapshot $snapshotFile ControlName ValueString NamesNotStored} error] {
        return -code error $error
    }
    set numNotStored [llength $NamesNotStored]
    #Communicating with PVs
    eval global env $ControlName
    if [catch {snapshot linkPVs $ControlName $timeOut errorTclNameList} error] {
        return -code error $error
    }
    if [catch {snapshot putPVs $ControlName $ValueString $timeOut 1 errorTclNameList} error] {
        return -code error $error
    }
    set numErrors [llength $errorTclNameList]

    #Write system log
    set logFile /home/helios/oagData/SCR/swapSpace/[APSTmpString].log
    set timeInSeconds [clock seconds]
    set log "SDDS1\n&parameter name = Time, type = long, &end\n"
    append log "&column name = ControlName, type = string, &end\n"
    append log "&data mode = ascii, &end\n! page number 1\n$timeInSeconds\n\t[expr $numErrors + $numNotStored]"
    if {$numNotStored} {
        append log \n[join $NamesNotStored \n]
    }
    if {$numErrors} {
        append log \n[join $errorTclNameList \n]
    }
    if [catch {open $logFile w} fileID] {
        return -code error $fileID
    }
    puts $fileID $log
    catch {close $fileID}
    file attributes $logFile -permissions 0775

    return -code ok [list $snapshotFile $logFile "$numNotStored PVs were not stored in the snapshot file\n$numErrors PVs not connected"]
}

set parser [interp create -safe]

$parser alias getvalues getvalues
$parser alias setvalues setvalues
$parser alias loadSnapshotLib loadSnapshotLib
$parser eval {
    loadSnapshotLib
}

proc server_accept {cid addr port} {
    fileevent $cid readable "server_handle $cid"
    fconfigure $cid -buffering line
}

proc server_handle {cid} {
    if {[gets $cid request] < 0} {
        close $cid
    } else {
        global parser buffer 
        append buffer $request "\n"
        if {[info complete $buffer]} {
            set request $buffer
            set buffer ""
            if {[catch {$parser eval $request} result]} {
                puts $cid [list error_result $result]
            } else {
                puts $cid "finished $result"
            }
            close $cid
        }
    }
}

proc server_accept_quit {args} {
    exit
}

set args $argv
set force 0
set kill 0

if [APSStrictParseArguments {force kill}] {
    puts stderr "usage: tclcaGPServer \[-force \[1|0\] | -kill \[1|0\]\]\n[join [split $CVSRevisionAuthor $] ""]"
    exit 1
}

#port 4577 is used for connections with tclcaget and tclcaput
if [catch {socket -server server_accept 4577}] {    
    if {$force || $kill} {
        if [catch {socket localhost 4578} sid] {
            puts stderr "Unable to close previous version of tclcaGPServer: $sid"
            exit 1
        } else {
            if {$kill} {
                exit
            }
            after 200
            if [catch {socket -server server_accept 4577}] {
                puts stderr "Unable to close previous version of tclcaGPServer"
                exit 1
            }
        }
    } else {
        puts stderr "port already in use, terminating program"
        exit 1
    }
}

if {$kill} {
    exit
}

#port 4578 is used to tell the server to quit
if [catch {socket -server server_accept_quit 4578}] {
    puts stderr "port already in use, terminating program"
    exit 1
}

vwait enter-mainloop
