' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Partial Public Class Logic

    Public Class ExceptionLog

        Public Enum EventOption
            Exception
            ThreadException
            UnhandledException
        End Enum

        Public Sub New(Optional ByVal Path As Logic.FileSystem.Path = Nothing, Optional ByVal LogFileOpenWaitTimeLimit As Integer = -1)
            Me.Path = Path
            Me.LogFileOpenWaitTimeLimit = LogFileOpenWaitTimeLimit
        End Sub

        Public Sub Append(ex_log As Exception, Optional ByVal opt As EventOption = EventOption.Exception, Optional ByVal IsMessageBox As Boolean = True)
            Append(IIf(Path Is Nothing, Logic.FileSystem.JoinPathElements(ExecutingLocation.UserAppDataPath.ToString, "exception.txt"), Path),
                   ex_log, opt, IsMessageBox, LogFileOpenWaitTimeLimit)
        End Sub

        Public Shared Sub Append(Path As Logic.FileSystem.Path, ex_log As Exception, Optional ByVal opt As EventOption = EventOption.Exception, Optional ByVal IsMessageBox As Boolean = True, Optional ByVal LogFileOpenWaitTimeLimit As Integer = -1)

            If Path Is Nothing OrElse Path.IsNullOrWhiteSpace OrElse ex_log Is Nothing Then Return

            Dim PathParent As Logic.FileSystem.Path = Path.Parent
            If PathParent.DirectoryExists = False Then IO.Directory.CreateDirectory(PathParent.ToString)

            Dim LogMessage As String = String.Format("Exception happened. Check error log.{0}{1}", vbCrLf, Path.ToString)
            Dim LogException As String = Nothing
            Dim isLoggingFailed = False
            Dim Mutex As System.Threading.Mutex = Nothing
            Try
                LogException = Logic.String.FromException(ex_log)
                Dim LockName As String = Logic.ExecutingLocation.ProductName & " LogAccessMutexNameOf " & Path.ToString.Replace(IO.Path.DirectorySeparatorChar, "").Replace(".", "")
                Mutex = Threading.CreateOrWaitMutex(LockName, LogFileOpenWaitTimeLimit)
                If Mutex Is Nothing Then
                    isLoggingFailed = True
                Else
                    Dim Assembly As Reflection.Assembly = Reflection.Assembly.GetEntryAssembly
                    Using LogWriter As New System.IO.StreamWriter(Path.ToString, True)
                        LogWriter.WriteLine(Assembly.ToString)
                        LogWriter.WriteLine(Assembly.Location)
                        LogWriter.WriteLine(opt.ToString & " happened at " & Now.ToString("yyyyMMdd_HHmmss"))
                        LogWriter.WriteLine(Logic.String.FromException(ex_log, vbTab, 1))
                    End Using
                End If
            Catch ex As Exception
                isLoggingFailed = True
            Finally
                If Mutex IsNot Nothing Then Mutex.Dispose()
            End Try

            If IsMessageBox Then
                If isLoggingFailed Then
                    LogMessage = "LogFile Access Error."
                    If String.IsNullOrWhiteSpace(LogException) = False Then LogMessage &= vbCrLf & LogException
                End If
                MsgBox(LogMessage, , "Application Error")
            End If

        End Sub

        Public Sub ThreadException(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs)
            Append(e.Exception, EventOption.ThreadException)
        End Sub

        Public Sub UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
            Append(TryCast(e.ExceptionObject, Exception), EventOption.UnhandledException)
        End Sub

        Private Path As Logic.FileSystem.Path
        Private LogFileOpenWaitTimeLimit As Integer

    End Class

End Class
