' Gambas module file

Export 
'CREATE 

Private $hManager As SessionManager
Private $sType As String = "sqlite"

Private $sId As String

Private $sPrefix As String
Private $bUnique As Boolean
Private $sCookiePath As String
Private $bInit As Boolean

'' Return or set the session type.
''
'' The supported types are:
''
'' [[
'' ==
'' 'file'
'' -
'' The session is serialized in a binary file.
'' ==
'' 'sqlite'
'' --
'' The session is stored in a SQLite3 file. The [/comp/gb.db.sqlite3] component is automatically loaded if needed.
'' ]]
Property Type As String

Property Id As String
Property Timeout As Float
Property Prefix As String
Property Unique As Boolean
Property Modified As Boolean
Property CookiePath As String
Property Read Keys As String[]

'' Return the session file size.
Property Read Size As Long

'' Return the session file path.
Property Read Path As String

Private Sub CreateSession()

  Dim sCookiePath As String
  
  If $hManager Then Return
  
  Select Case $sType
    Case "file"
      $hManager = New FileSessionManager($sId)
    Case Else
      $hManager = New SqliteSessionManager($sId)
  End Select
  
  If Not $sId Then
    $hManager.Create()
  Else
    If $hManager.Load() Then Return
  Endif
  
  sCookiePath = GetCookiePath()
  $hManager["_"] = sCookiePath
  
  Main.Log("CreateSession: " & $sId)
  Response.SetCookie("GBSESSIONID", $sId, "", sCookiePath,, True)

End

Private Sub CheckAllowLog()

  If $bInit Then Return
  Main.AllowLog = Exist("/tmp/session.debug")

End

Private Sub Init()
  
  If $bInit Then Return

  CheckAllowLog
  
  $bInit = True
  
  'Main.Log("Session.Init")
  
  'Main.Log("HTTP_COOKIE = " & CGI["HTTP_COOKIE"] & " / " & Env["HTTP_COOKIE"])
  $sId = Request.Cookies["GBSESSIONID"]
  Main.Log("--------------- Init: Cookie = " & $sId)
  
  'Main.Log("Cookie = " & $sId)
  '$sId = "9E2496B3AB6DDED93ABE6F0CF6E071B3@"
  If Not $sId Then Return
  
  CreateSession
  
'CATCH 
'  CGI.Error(Error.Where & ": " & Error.Text)

End

Public Sub _exit()
  
  Try Main.Log("Session._exit")
  If $hManager Then $hManager.Exit
  
End

Private Sub GetCookiePath() As String

  Dim sPath As String
  
  If $sCookiePath Then Return $sCookiePath
  
  sPath = CGI["SCRIPT_NAME"]
  If sPath = "/." Then sPath = "/"
  Return sPath

End

Public Sub Abandon()
  
  Dim sCookiePath As String
  
  Init
  
  Main.Log("Abandon: " & $sId)
  
  If $hManager Then
    sCookiePath = $hManager["_"]
  Else
    sCookiePath = GetCookiePath()
  Endif
  
  Response.RemoveCookie("GBSESSIONID", "", "", sCookiePath)
  
  If Not $sId Then Return
  If Not $hManager Then Return

  Try Object.Call(Application.Startup, "Session_Abandon")

  $hManager.Abandon

  $sId = ""
  $hManager = Null
  
  Main.Log("Abandon FIN")
  
End

Public Sub _get(Key As String) As Variant
  
  Init
  If $hManager Then Return $hManager[Key]
  
End

Public Sub Exist(Key As String) As Boolean
  
  Init
  If $hManager Then Return $hManager.Exist(Key)
  
End


Public Sub _put(Value As Variant, Key As String)

  Init
  If Not $hManager Then CreateSession
  $hManager[Key] = Value
    
End


Private Function Id_Read() As String

  Init
  Return $sId  

End


Private Sub Id_Write(Value As String)

  Init
  Abandon
  $sId = Value
  CreateSession

End

Private Function Timeout_Read() As Float

  Init
  Return Int($hManager.Timeout * 86400 + 0.5)

End

Private Sub Timeout_Write(Value As Float)

  Init
  $hManager.Timeout = Value / 86400

End

Public Sub Save()
  
  Init
  $hManager.Save
  
End

Public Sub Load()

  Init
  $hManager.Load
  
End


Private Function Prefix_Read() As String

  Return $sPrefix

End

Private Sub Prefix_Write(Value As String)

  $sPrefix = Value

End

Private Function Unique_Read() As Boolean

  Return $bUnique

End

Private Sub Unique_Write(Value As Boolean)

  $bUnique = Value
  If $hManager Then $hManager.CheckUnique

End

Private Function Modified_Read() As Boolean

  Return $hManager.Modified

End

Private Sub Modified_Write(Value As Boolean)

  Init
  $hManager.Modified = Value

End

Private Function CookiePath_Read() As String

  Return $sCookiePath

End

Private Sub CookiePath_Write(Value As String)

  $sCookiePath = Value

End


Private Function Keys_Read() As String[]

  Return $hManager.GetKeys()

End

Private Function Size_Read() As Long

  Try Return $hManager.Size

End


Private Function Type_Read() As String

  Return $sType

End

Private Sub Type_Write(Value As String)

  Value = LCase(Value)
  Select Case Value
    Case "sqlite", "file"
      $sType = Value
    Case ""
      $sType = "sqlite"
    Case Else
      Error.Raise("Unknown session type")
  End Select

End

Public Sub _MakeId()
  
  Dim iInd As Integer
  
  $sId = ""
  For iInd = 1 To 6
    $sId &= Hex$(Int(Rnd(65536)), 4)
  Next
  If $sPrefix Then
    $sId = $sPrefix & ":" & $sId
  Else
    $sId = CGI["REMOTE_ADDR"] & ":" & $sId
  Endif
  
End


Private Function Path_Read() As String

  Return $hManager.GetPath()

End
