<%
' Universal data caching system for frequently accessed database queries
' Uses Application-level cache with configurable TTL (Time To Live)

' Cache durations in minutes
Const CACHE_DROPDOWN_TTL = 60      ' Dropdowns (vendors, models) - 1 hour
Const CACHE_LIST_TTL = 5           ' List pages (printers, machines) - 5 minutes
Const CACHE_STATIC_TTL = 1440      ' Static data (rarely changes) - 24 hours

'=============================================================================
' DROPDOWN DATA CACHING (Vendors, Models, etc.)
'=============================================================================

' Get all printer vendors (cached)
Function GetPrinterVendorsCached()
    Dim cacheKey, cacheAge, cachedData
    cacheKey = "dropdown_printer_vendors"

    ' Check cache
    If Not IsEmpty(Application(cacheKey)) Then
        cacheAge = DateDiff("n", Application(cacheKey & "_time"), Now())
        If cacheAge < CACHE_DROPDOWN_TTL Then
            GetPrinterVendorsCached = Application(cacheKey)
            Exit Function
        End If
    End If

    ' Fetch from database
    Dim sql, rs_temp, resultArray(), count, i
    sql = "SELECT vendorid, vendor FROM vendors WHERE isprinter=1 AND isactive=1 ORDER BY vendor ASC"

    Set rs_temp = objConn.Execute(sql)

    ' Count rows
    count = 0
    While Not rs_temp.EOF
        count = count + 1
        rs_temp.MoveNext
    Wend

    If count = 0 Then
        Set rs_temp = Nothing
        GetPrinterVendorsCached = Array()
        Exit Function
    End If

    ' Reset to beginning
    rs_temp.MoveFirst

    ' Build array
    ReDim resultArray(count - 1, 1) ' vendorid, vendor
    i = 0
    While Not rs_temp.EOF
        resultArray(i, 0) = rs_temp("vendorid")
        resultArray(i, 1) = rs_temp("vendor")
        i = i + 1
        rs_temp.MoveNext
    Wend

    rs_temp.Close
    Set rs_temp = Nothing

    ' Cache it
    Application.Lock
    Application(cacheKey) = resultArray
    Application(cacheKey & "_time") = Now()
    Application.Unlock

    GetPrinterVendorsCached = resultArray
End Function

' Get all printer models (cached)
Function GetPrinterModelsCached()
    Dim cacheKey, cacheAge, cachedData
    cacheKey = "dropdown_printer_models"

    ' Check cache
    If Not IsEmpty(Application(cacheKey)) Then
        cacheAge = DateDiff("n", Application(cacheKey & "_time"), Now())
        If cacheAge < CACHE_DROPDOWN_TTL Then
            GetPrinterModelsCached = Application(cacheKey)
            Exit Function
        End If
    End If

    ' Fetch from database
    Dim sql, rs_temp, resultArray(), count, i
    sql = "SELECT models.modelnumberid, models.modelnumber, vendors.vendor " & _
          "FROM vendors, models " & _
          "WHERE models.vendorid = vendors.vendorid " & _
          "AND vendors.isprinter=1 AND models.isactive=1 " & _
          "ORDER BY modelnumber ASC"

    Set rs_temp = objConn.Execute(sql)

    ' Count rows
    count = 0
    While Not rs_temp.EOF
        count = count + 1
        rs_temp.MoveNext
    Wend

    If count = 0 Then
        Set rs_temp = Nothing
        GetPrinterModelsCached = Array()
        Exit Function
    End If

    ' Reset to beginning
    rs_temp.MoveFirst

    ' Build array
    ReDim resultArray(count - 1, 2) ' modelnumberid, modelnumber, vendor
    i = 0
    While Not rs_temp.EOF
        resultArray(i, 0) = rs_temp("modelnumberid")
        resultArray(i, 1) = rs_temp("modelnumber")
        resultArray(i, 2) = rs_temp("vendor")
        i = i + 1
        rs_temp.MoveNext
    Wend

    rs_temp.Close
    Set rs_temp = Nothing

    ' Cache it
    Application.Lock
    Application(cacheKey) = resultArray
    Application(cacheKey & "_time") = Now()
    Application.Unlock

    GetPrinterModelsCached = resultArray
End Function

'=============================================================================
' LIST PAGE CACHING (Printer list, Machine list, etc.)
'=============================================================================

' Get all active printers (cached) - for displayprinters.asp
Function GetPrinterListCached()
    Dim cacheKey, cacheAge
    cacheKey = "list_printers"

    ' Check cache
    If Not IsEmpty(Application(cacheKey)) Then
        cacheAge = DateDiff("n", Application(cacheKey & "_time"), Now())
        If cacheAge < CACHE_LIST_TTL Then
            GetPrinterListCached = Application(cacheKey)
            Exit Function
        End If
    End If

    ' Fetch from database
    Dim sql, rs_temp, resultArray(), count, i
    sql = "SELECT printers.printerid AS printer, printers.*, vendors.*, models.*, machines.* " & _
          "FROM printers, vendors, models, machines " & _
          "WHERE printers.modelid=models.modelnumberid " & _
          "AND models.vendorid=vendors.vendorid " & _
          "AND printers.machineid=machines.machineid " & _
          "AND printers.isactive=1 " & _
          "ORDER BY machinenumber ASC"

    Set rs_temp = objConn.Execute(sql)

    ' Count rows
    count = 0
    While Not rs_temp.EOF
        count = count + 1
        rs_temp.MoveNext
    Wend

    If count = 0 Then
        Set rs_temp = Nothing
        GetPrinterListCached = Array()
        Exit Function
    End If

    rs_temp.MoveFirst

    ' Build array with all needed fields
    ReDim resultArray(count - 1, 11) ' printer, image, installpath, machinenumber, machineid, vendor, modelnumber, documentationpath, printercsfname, ipaddress, serialnumber, islocationonly
    i = 0
    While Not rs_temp.EOF
        resultArray(i, 0) = rs_temp("printer")
        resultArray(i, 1) = rs_temp("image")
        resultArray(i, 2) = rs_temp("installpath")
        resultArray(i, 3) = rs_temp("machinenumber")
        resultArray(i, 4) = rs_temp("machineid")
        resultArray(i, 5) = rs_temp("vendor")
        resultArray(i, 6) = rs_temp("modelnumber")
        resultArray(i, 7) = rs_temp("documentationpath")
        resultArray(i, 8) = rs_temp("printercsfname")
        resultArray(i, 9) = rs_temp("ipaddress")
        resultArray(i, 10) = rs_temp("serialnumber")

        ' Convert islocationonly bit to 1/0 integer (bit fields come as binary)
        On Error Resume Next
        If IsNull(rs_temp("islocationonly")) Then
            resultArray(i, 11) = 0
        Else
            ' Convert bit field to integer (0 or 1)
            resultArray(i, 11) = Abs(CBool(rs_temp("islocationonly")))
        End If
        On Error Goto 0

        i = i + 1
        rs_temp.MoveNext
    Wend

    rs_temp.Close
    Set rs_temp = Nothing

    ' Cache it
    Application.Lock
    Application(cacheKey) = resultArray
    Application(cacheKey & "_time") = Now()
    Application.Unlock

    GetPrinterListCached = resultArray
End Function

'=============================================================================
' HELPER FUNCTIONS
'=============================================================================

' Render dropdown options from cached vendor data
Function RenderVendorOptions(selectedID)
    Dim vendors, output, i
    vendors = GetPrinterVendorsCached()
    output = ""

    On Error Resume Next
    If Not IsArray(vendors) Or UBound(vendors) < 0 Then
        RenderVendorOptions = ""
        Exit Function
    End If
    On Error Goto 0

    For i = 0 To UBound(vendors)
        If CLng(vendors(i, 0)) = CLng(selectedID) Then
            output = output & "<option value='" & vendors(i, 0) & "' selected>" & vendors(i, 1) & "</option>"
        Else
            output = output & "<option value='" & vendors(i, 0) & "'>" & vendors(i, 1) & "</option>"
        End If
    Next

    RenderVendorOptions = output
End Function

' Render dropdown options from cached model data
Function RenderModelOptions(selectedID)
    Dim models, output, i
    models = GetPrinterModelsCached()
    output = ""

    On Error Resume Next
    If Not IsArray(models) Or UBound(models) < 0 Then
        RenderModelOptions = ""
        Exit Function
    End If
    On Error Goto 0

    For i = 0 To UBound(models)
        If CLng(models(i, 0)) = CLng(selectedID) Then
            output = output & "<option value='" & models(i, 0) & "' selected>" & models(i, 1) & "</option>"
        Else
            output = output & "<option value='" & models(i, 0) & "'>" & models(i, 1) & "</option>"
        End If
    Next

    RenderModelOptions = output
End Function

' Get all support teams (cached) - for application dropdowns
Function GetSupportTeamsCached()
    Dim cacheKey, cacheAge, cachedData
    cacheKey = "dropdown_support_teams"

    ' Check cache
    If Not IsEmpty(Application(cacheKey)) Then
        cacheAge = DateDiff("n", Application(cacheKey & "_time"), Now())
        If cacheAge < CACHE_DROPDOWN_TTL Then
            GetSupportTeamsCached = Application(cacheKey)
            Exit Function
        End If
    End If

    ' Fetch from database
    Dim sql, rs_temp, resultArray(), count, i
    sql = "SELECT supporteamid, teamname FROM supportteams WHERE isactive=1 ORDER BY teamname ASC"

    Set rs_temp = objConn.Execute(sql)

    ' Count rows
    count = 0
    While Not rs_temp.EOF
        count = count + 1
        rs_temp.MoveNext
    Wend

    If count = 0 Then
        Set rs_temp = Nothing
        GetSupportTeamsCached = Array()
        Exit Function
    End If

    ' Reset to beginning
    rs_temp.MoveFirst

    ' Build array
    ReDim resultArray(count - 1, 1) ' supporteamid, teamname
    i = 0
    While Not rs_temp.EOF
        resultArray(i, 0) = rs_temp("supporteamid")
        resultArray(i, 1) = rs_temp("teamname")
        i = i + 1
        rs_temp.MoveNext
    Wend

    rs_temp.Close
    Set rs_temp = Nothing

    ' Cache it
    Application.Lock
    Application(cacheKey) = resultArray
    Application(cacheKey & "_time") = Now()
    Application.Unlock

    GetSupportTeamsCached = resultArray
End Function

' Render dropdown options from cached support team data
Function RenderSupportTeamOptions(selectedID)
    Dim teams, output, i
    teams = GetSupportTeamsCached()
    output = ""

    On Error Resume Next
    If Not IsArray(teams) Or UBound(teams) < 0 Then
        RenderSupportTeamOptions = ""
        Exit Function
    End If
    On Error Goto 0

    For i = 0 To UBound(teams)
        If CLng(teams(i, 0)) = CLng(selectedID) Then
            output = output & "<option value='" & teams(i, 0) & "' selected>" & Server.HTMLEncode(teams(i, 1)) & "</option>"
        Else
            output = output & "<option value='" & teams(i, 0) & "'>" & Server.HTMLEncode(teams(i, 1)) & "</option>"
        End If
    Next

    RenderSupportTeamOptions = output
End Function

' Clear dropdown cache (call after adding/editing vendors or models)
Sub ClearDropdownCache()
    Application.Lock
    Application("dropdown_printer_vendors") = Empty
    Application("dropdown_printer_vendors_time") = Empty
    Application("dropdown_printer_models") = Empty
    Application("dropdown_printer_models_time") = Empty
    Application("dropdown_support_teams") = Empty
    Application("dropdown_support_teams_time") = Empty
    Application.Unlock
End Sub

' Clear list cache (call after adding/editing printers)
Sub ClearListCache()
    Application.Lock
    Application("list_printers") = Empty
    Application("list_printers_time") = Empty
    Application.Unlock
End Sub

' Clear ALL data cache
Sub ClearAllDataCache()
    Dim key, keysToRemove(), count, i
    count = 0

    ' First pass: collect keys to remove
    ReDim keysToRemove(100) ' Initial size
    For Each key In Application.Contents
        If Left(key, 9) = "dropdown_" Or Left(key, 5) = "list_" Then
            keysToRemove(count) = key
            count = count + 1
            If count Mod 100 = 0 Then
                ReDim Preserve keysToRemove(count + 100)
            End If
        End If
    Next

    ' Second pass: remove collected keys
    Application.Lock
    For i = 0 To count - 1
        Application.Contents.Remove(keysToRemove(i))
    Next
    Application.Unlock
End Sub

' Get cache stats
Function GetCacheStats()
    Dim stats, key, count
    count = 0

    For Each key In Application.Contents
        If Left(key, 9) = "dropdown_" Or Left(key, 5) = "list_" Or Left(key, 7) = "zabbix_" Then
            If Right(key, 5) <> "_time" And Right(key, 11) <> "_refreshing" Then
                count = count + 1
            End If
        End If
    Next

    stats = "Cached items: " & count
    GetCacheStats = stats
End Function
%>
