Imports System.Data.SqlClient
Imports System.IO
Imports Svg

Public Class DefaultAppSig
    Inherits System.Web.UI.Page

    Protected Sub Page_Load() Handles Me.Load
        Dim appId As Integer = Request.Params("appId")
        Dim accountId = SessionVars.DriverId(Session)
        _VerifyAccess(appId, accountId)

        Select Case CStr(Request.Form("action"))
            Case "get"
                _Get(appId)
            Case "update"
                _Update(appId, Request.Form("data"))
            Case Else
                Throw New HttpException(400, "Bad Request")
        End Select
    End Sub

    Private Sub _Get(appId As Integer)
        Using connection As New SqlConnection(Logic.Database.connectionString)
            connection.Open()
            Dim cmd As New SqlCommand(
                "SELECT sig.data 
                FROM web_DriverApplication app
                LEFT JOIN web_Signature sig ON sig.id=app.defaultSignatureId
                WHERE app.id=@appId", connection)
            cmd.Parameters.AddWithValue("appId", appId)
            Dim data = cmd.ExecuteScalar()

            If IsDBNull(data) Then
                Throw New HttpException(404, "Not Found")
            Else
                Response.ContentType = "image/svg+xml"
                Response.Clear()
                Response.Write(data)
                Response.End()
            End If
        End Using
    End Sub

    Private Function _IsEmpty(data As String) As Boolean

        ' Pull info from data
        Dim parts = New Regex("^(?:data:)?(.*?);base64,(.*?)$").Match(data)
        If parts.Groups.Count <> 3 Then Return True ' can't read, assume empty
        Dim mimeType = parts.Groups(1).Value
        Dim base64Data = parts.Groups(2).Value
        base64Data = base64Data.PadRight(base64Data.Length + (base64Data.Length Mod 4), "="c)
        Dim bytes = Convert.FromBase64String(base64Data)
        
        ' Actual test
        Using memStream As New MemoryStream(bytes)
            Dim svg = SvgDocument.Open(Of SvgDocument)(memStream)
            If svg.Width = 0 Or svg.Height = 0 Then Return True
        End Using
        Return false

    End Function

    Private Sub _Update(appId As Integer, data As String)
        If _IsEmpty(data) Then Throw New HttpException(400, "Bad Request")
        Using connection As New SqlConnection(Logic.Database.connectionString)
            connection.Open()
            Dim cmd As New SqlCommand("", connection)
            cmd.Parameters.AddWithValue("appId", appId)
            cmd.Parameters.AddWithValue("ipAddress", Request.UserHostAddress)

            ' First get the signature we'll be updating.
            Dim defaultSignatureId As Integer
            cmd.CommandText = "SELECT defaultSignatureId FROM web_DriverApplication WHERE id=@appId"
            Dim defaultSignatureIdObj = cmd.ExecuteScalar()
            If Not IsDBNull(defaultSignatureIdObj) Then
                defaultSignatureId = defaultSignatureIdObj
                cmd.Parameters.AddWithValue("sigId", defaultSignatureId)
            Else ' If nonexistent, we need to create the sig and tie it to the app:
                cmd.CommandText =
                    "INSERT INTO web_Signature (dateSigned,signerIp,context) 
                    VALUES (GETDATE(),@ipAddress,'');
                    SELECT @@IDENTITY;"
                defaultSignatureId = cmd.ExecuteScalar()
                cmd.CommandText = "UPDATE web_DriverApplication SET defaultSignatureId=@sigId WHERE id=@appId"
                cmd.Parameters.AddWithValue("sigId", defaultSignatureId)
                cmd.ExecuteNonQuery()
            End If

            ' Update the signature data
            cmd.CommandText = "UPDATE web_Signature SET data=@data WHERE id=@sigId"
            cmd.Parameters.AddWithValue("data", data)
            cmd.ExecuteNonQuery()

        End Using

        Response.ContentType = "text/xml"
    End Sub

    Private Sub _VerifyAccess(appId As Integer, accountId As Integer)
        Using connection As New SqlConnection(Logic.Database.connectionString)
            connection.Open()
            Dim cmd As New SqlCommand(
                "SELECT COUNT(id) FROM web_DriverApplication
                WHERE id=@appId AND driverAccountId=@accountId",
                connection)
            cmd.Parameters.AddWithValue("appId", appId)
            cmd.Parameters.AddWithValue("accountId", accountId)
            If CInt(cmd.ExecuteScalar()) <> 1 Then
                Throw New HttpException(403, "Forbidden")
            End If
        End Using
    End Sub

End Class