#!/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)]

APSStandardSetup


proc GetIOCInfo {category subcategory zone} {
    global iocList iocStatusList
    set nameTagPair [exec sdds2stream /home/helios/oagData/deviceConfig/IOCs.sdds -col=Name,Tag]
    
    set iocList ""
    foreach "ioc tag" $nameTagPair {
        set beamline [lindex [split $tag ,] 0]
        set sector [lrange [split $tag ,] 1 end]
        if {($beamline == $category) && (($sector == $subcategory) || ($subcategory == ""))} {
            if {$zone == ""} {
                lappend iocList $ioc
            } elseif {$zone == "A"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector >= 2) && ($sector <= 9)} {
                    lappend iocList $ioc
                }
            } elseif {$zone == "B"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector >= 10) && ($sector <= 17)} {
                    lappend iocList $ioc
                }
            } elseif {$zone == "C"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector >= 18) && ($sector <= 23)} {
                    lappend iocList $ioc
                }
            } elseif {$zone == "D"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector >= 24) && ($sector <= 29)} {
                    lappend iocList $ioc
                }
            } elseif {$zone == "E"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector >= 30) && ($sector <= 35)} {
                    lappend iocList $ioc
                }
            } elseif {$zone == "F"} {
                set sector [string trimleft [string range $ioc 5 6] 0]
                if {($sector == 1) || (($sector >= 36) && ($sector <= 40))} {
                    lappend iocList $ioc
                }
            }
        }
    }
    if {[catch {APScavget -pend=2 -list=[join ${iocList} ,] -list=:status} iocStatusList]} {
        puts "Error: $iocStatusList"
        exit
    }
}


proc GetPVs {category subcategory} {
    global allPVs setablePVs readonlyPVs iocList iocStatusList
    
    set setablePVs ""
    set readonlyPVs ""

    puts "Identifying PVs for ${category} ${subcategory}"
    foreach ioc $iocList status $iocStatusList {
        if {$status == "1"} {
            if {[file exists /home/helios/iocinfo/pvdata/$ioc]} {
                if {[catch {exec plaindata2sdds /home/helios/iocinfo/pvdata/$ioc -pipe=out \
                              -noRowCount -col=Name,string | sdds2stream -pipe=in -col=Name} PVnames]} {
                    puts "Error: $ioc $PVnames"
                    exit
                }
                foreach pv $PVnames {
                    if {$category == "IETS"} {
                        if {[string first "IETS" $pv] != -1} {
                            if {[string index $pv end] == "C"} {
                                set char [string index $pv end-1]
                                if {[string is upper $char] || [string is digit $char]} {
                                    lappend readonlyPVs $pv
                                } else {
                                    lappend setablePVs $pv
                                }
                            } else {
                                lappend readonlyPVs $pv
                            }
                        }
                    } elseif {$category == "SR"} {
                        if {[string match "S??LB?:EVRX:Pll_OsUnlockTimeResetC" $pv]} {
                            continue
                        }
                        if {[string match "ioc2s??bpm?:evrx:pll:os_unlock_time:reset" $pv]} {
                            continue
                        }
                        if {[string match "S??-*MPS:MainLink-Sts" $pv]} {
                            continue
                        }
                        if {[string match "S??-MPS:LMPS:MainLinkStatusM" $pv]} {
                            continue
                        }
                        if {[string match "S??-*MPS:X10:SFP_Loss-Sts*" $pv]} {
                            continue
                        }
                        if {[string match "S??-*MPS:X10:TX_Fault-Sts*" $pv]} {
                            continue
                        }
                        if {[string index $pv end] == "C"} {
                            set char [string index $pv end-1]
                            if {[string is upper $char] || [string is digit $char]} {
                                lappend readonlyPVs $pv
                            } else {
                                lappend setablePVs $pv
                            }
                        } elseif {[string range $pv end-1 end] == "AI"} {
                            set char [string index $pv end-2]
                            if {[string is upper $char]} {
                                lappend readonlyPVs $pv
                            } else {
                                lappend setablePVs $pv
                            }
                        } else {
                            lappend readonlyPVs $pv
                        }                    
                    } elseif {$category == "Booster"} {
                        if {[string range $pv end-1 end] == "AI"} {
                            set char [string index $pv end-2]
                            if {[string is upper $char]} {
                                lappend readonlyPVs $pv
                            } else {
                                lappend setablePVs $pv
                            }
                        } else {
                            lappend readonlyPVs $pv
                        }                    
                    }
                }
            }
        } 
    }
    set allPVs "$setablePVs $readonlyPVs"
}

proc WriteBaselineRequestFile {category subcategory zone} {
    global allPVs setablePVs readonlyPVs iocList iocStatusList
    set data(ColumnNames) "ControlName"
    set data(Column.ControlName) [list $allPVs]
    set sub [join [split $subcategory] ""]
    if {$zone != ""} {
        append sub "_Zone$zone"
    }
    sdds save ../requestFiles/Baseline${category}${sub}.tmp data

    puts "Working on Baseline${category}${sub}.req"
    exec sddscainfo ../requestFiles/Baseline${category}${sub}.tmp ../requestFiles/Baseline${category}${sub}.test -pend=10
    puts "sddscainfo done"
    file delete ../requestFiles/Baseline${category}${sub}.tmp
    unset data
    
    sdds load ../requestFiles/Baseline${category}${sub}.test data
    file delete ../requestFiles/Baseline${category}${sub}.test
    foreach cn [lindex $data(Column.ControlName) 0] \
      active [lindex $data(Column.Active) 0] \
      provider [lindex $data(Column.Provider) 0] \
      readAccess [lindex $data(Column.ReadAccess) 0] \
      writeAccess [lindex $data(Column.WriteAccess) 0] \
      fieldType [lindex $data(Column.FieldType) 0] \
      elementCount [lindex $data(Column.ElementCount) 0] \
      nativeDataType [lindex $data(Column.NativeDataType) 0] \
      units [lindex $data(Column.Units) 0] {
          if {$active == "n"} {
              puts "$cn not Active"
              exit
          }
          if {$provider == "pva"} {
              puts "$cn is PVA channel"
              exit
          }
          if {$readAccess == "n"} {
              puts "$cn not readable"
              exit
          }
          
          append out(Column.ControlName) "$cn "
          if {$category == "IETS"} {
              append out(Column.Beamline) "SR "
              append out(Column.Category) "IETS "
          } elseif {$category == "SR"} {
              append out(Column.Beamline) "SR "
              append out(Column.Category) "$sub "
          } elseif {$category == "Booster"} {
              append out(Column.Beamline) "Booster "
              append out(Column.Category) "$sub "
          }
          append out(Column.Tolerance) "0.000001 "
          append out(Column.OpsIntervention) "y "
          append out(Column.IsProtected) "y "
          set units [string trim $units]
          if {$units == ""} {
              append out(Column.ReadbackUnits) "\"\" "
          } else {
              if {[llength $units] > 1} {
                  append out(Column.ReadbackUnits) "\"$units\" "
              } else {
                  append out(Column.ReadbackUnits) "$units "
              }
          }
          
          if {[lsearch -exact $readonlyPVs $cn] >= 0} {
              append out(Column.IsReadonly) "y "
          } else {
              set value n
              if {$writeAccess == "n"} {
                  if {[lsearch -exact $setablePVs $cn] >= 0} {
                      puts "$cn not writable"
                      set value y
                  }
              }
              append out(Column.IsReadonly) "$value "
          }
          
          if {$fieldType == "scalarArray"} {
              append out(Column.IsNumerical) "n "
              append out(Column.ExpectNumeric) "n "
              append out(Column.ExpectFieldType) "scalarArray "
          } elseif {$fieldType == "ENUM structure"} {
              append out(Column.IsNumerical) "n "
              append out(Column.ExpectNumeric) "n "
              append out(Column.ExpectFieldType) "scalar "
          } elseif {$nativeDataType == "string"} {
              append out(Column.IsNumerical) "n "
              append out(Column.ExpectNumeric) "n "
              append out(Column.ExpectFieldType) "scalar "
          } elseif {$nativeDataType == "byte"} {
              append out(Column.IsNumerical) "n "
              append out(Column.ExpectNumeric) "n "
              append out(Column.ExpectFieldType) "scalar "
          } elseif {$nativeDataType == "ubyte"} {
              append out(Column.IsNumerical) "n "
              append out(Column.ExpectNumeric) "n "
              append out(Column.ExpectFieldType) "scalar "
          } else {
              append out(Column.IsNumerical) "y "
              append out(Column.ExpectNumeric) "y "
              append out(Column.ExpectFieldType) "scalar "
          }
          append out(Column.Provider) "$provider "
          append out(Column.ExpectElements) "$elementCount "
      }
    set out(ColumnNames) "ControlName Beamline Category Tolerance IsNumerical OpsIntervention IsReadonly IsProtected ReadbackUnits Provider ExpectNumeric ExpectFieldType ExpectElements"
    set out(ParameterNames) "InstallLocation"
    set out(Parameter.InstallLocation) "/home/helios/oagData/SCR/requestFiles/Baseline${category}${sub}.req"
    set out(ColumnInfo.Tolerance) "type SDDS_DOUBLE"
    set out(ColumnInfo.IsNumerical) "type SDDS_CHARACTER"
    set out(ColumnInfo.OpsIntervention) "type SDDS_CHARACTER"
    set out(ColumnInfo.IsReadonly) "type SDDS_CHARACTER"
    set out(ColumnInfo.IsProtected) "type SDDS_CHARACTER"
    set out(ColumnInfo.ExpectNumeric) "type SDDS_CHARACTER"
    set out(ColumnInfo.ExpectElements) "type SDDS_LONG"

    set out(Column.ControlName) [list $out(Column.ControlName)]
    set out(Column.Beamline) [list $out(Column.Beamline)]
    set out(Column.Category) [list $out(Column.Category)]
    set out(Column.Tolerance) [list $out(Column.Tolerance)]
    set out(Column.IsNumerical) [list $out(Column.IsNumerical)]
    set out(Column.OpsIntervention) [list $out(Column.OpsIntervention)]
    set out(Column.IsReadonly) [list $out(Column.IsReadonly)]
    set out(Column.IsProtected) [list $out(Column.IsProtected)]
    set out(Column.ReadbackUnits) [list $out(Column.ReadbackUnits)]
    set out(Column.Provider) [list $out(Column.Provider)]
    set out(Column.ExpectNumeric) [list $out(Column.ExpectNumeric)]
    set out(Column.ExpectFieldType) [list $out(Column.ExpectFieldType)]
    set out(Column.ExpectElements) [list $out(Column.ExpectElements)]
    
    sdds save ../requestFiles/Baseline${category}${sub}.req out
}


if {0} {
GetIOCInfo Booster "Vacuum" ""
GetPVs Booster "Vacuum"
WriteBaselineRequestFile Booster "Vacuum" ""

GetIOCInfo Booster "Temperature" ""
GetPVs Booster "Temperature"
WriteBaselineRequestFile Booster "Temperature" ""

GetIOCInfo Booster "PS Vacuum" ""
GetPVs Booster "PS Vacuum"
WriteBaselineRequestFile Booster "PS Vacuum" ""

GetIOCInfo Booster PS ""
GetPVs Booster PS
WriteBaselineRequestFile Booster PS ""

GetIOCInfo Booster Interlock ""
GetPVs Booster Interlock 
WriteBaselineRequestFile Booster Interlock ""

#GetIOCInfo Booster BPM ""
#GetPVs Booster BPM 
#WriteBaselineRequestFile Booster BPM ""

GetIOCInfo SR "" ""
GetPVs IETS "" 
WriteBaselineRequestFile IETS "" ""


GetIOCInfo SR BPM A
GetPVs SR "BPM Zone A"
WriteBaselineRequestFile SR BPM A

GetIOCInfo SR BPM B
GetPVs SR "BPM Zone B"
WriteBaselineRequestFile SR BPM B

GetIOCInfo SR BPM C
GetPVs SR "BPM Zone C"
WriteBaselineRequestFile SR BPM C

GetIOCInfo SR BPM D
GetPVs SR "BPM Zone D"
WriteBaselineRequestFile SR BPM D

GetIOCInfo SR BPM E
GetPVs SR "BPM Zone E"
WriteBaselineRequestFile SR BPM E

GetIOCInfo SR BPM F
GetPVs SR "BPM Zone F"
WriteBaselineRequestFile SR BPM F

#GetIOCInfo SR "Control" ""
#GetPVs SR "Control"
#WriteBaselineRequestFile SR "Control" ""

#GetIOCInfo SR "DAQ" ""
#GetPVs SR "DAQ"
#WriteBaselineRequestFile SR "DAQ" ""

#GetIOCInfo SR "Diagnostic" ""
#GetPVs SR "Diagnostic"
#WriteBaselineRequestFile SR "Diagnostic" ""

GetIOCInfo SR "Diagnostic Motor" ""
GetPVs SR "Diagnostic Motor"
WriteBaselineRequestFile SR "Diagnostic Motor" ""

GetIOCInfo SR "Diagnostic Timing" ""
GetPVs SR "Diagnostic Timing"
WriteBaselineRequestFile SR "Diagnostic Timing" ""
}
GetIOCInfo SR Feedback ""
GetPVs SR Feedback
WriteBaselineRequestFile SR Feedback ""

if {0} {
#GetIOCInfo SR Front-End ""
#GetPVs SR Front-End
#WriteBaselineRequestFile SR Front-End ""

#GetIOCInfo SR ID/SCU ""
#GetPVs SR ID/SCU
#WriteBaselineRequestFile SR ID/SCU ""

GetIOCInfo SR Injection ""
GetPVs SR Injection
WriteBaselineRequestFile SR Injection ""

GetIOCInfo SR Interlock ""
GetPVs SR Interlock
WriteBaselineRequestFile SR Interlock ""

GetIOCInfo SR Motor ""
GetPVs SR Motor
WriteBaselineRequestFile SR Motor ""

GetIOCInfo SR "PS" ""
GetPVs SR "PS"
WriteBaselineRequestFile SR "PS" ""

GetIOCInfo SR "PS Injection" ""
GetPVs SR "PS Injection"
WriteBaselineRequestFile SR "PS Injection" ""

GetIOCInfo SR "PS Interlock" ""
GetPVs SR "PS Interlock"
WriteBaselineRequestFile SR "PS Interlock" ""

#GetIOCInfo SR RF ""
#GetPVs SR RF
#WriteBaselineRequestFile SR RF ""

#GetIOCInfo SR Safety ""
#GetPVs SR Safety
#WriteBaselineRequestFile SR Safety ""

#GetIOCInfo SR Temperature ""
#GetPVs SR Temperature
#WriteBaselineRequestFile SR Temperature ""

#GetIOCInfo SR Timing ""
#GetPVs SR Timing
#WriteBaselineRequestFile SR Timing ""

GetIOCInfo SR Vacuum ""
GetPVs SR Vacuum
WriteBaselineRequestFile SR Vacuum ""

}
puts DONE
