' OWIN 기반 정적 파일 호스팅 서버
'
' 사용 방법:
' Dim server As New StaticFileServer("C:\wwwroot", 58123)
' server.Start()
' ... 프로그램 실행 ...
' server.Stop()
Imports System
Imports System.IO
Imports Microsoft.Owin.Hosting
Namespace WebServer
    ''' 
    ''' OWIN 기반 정적 파일 호스팅 서버
    ''' 포트 58123 사용 (일반적으로 사용하지 않는 포트)
    ''' 
    Public Class StaticFileServer
        Implements IDisposable
        Private _webApp As IDisposable
        Private _baseUrl As String
        Private _rootPath As String
        Private _isRunning As Boolean = False
        ''' 
        ''' 서버가 실행 중인지 여부
        ''' 
        Public ReadOnly Property IsRunning As Boolean
            Get
                Return _isRunning
            End Get
        End Property
        ''' 
        ''' 서버 URL (예: http://localhost:58123)
        ''' 
        Public ReadOnly Property BaseUrl As String
            Get
                Return _baseUrl
            End Get
        End Property
        ''' 
        ''' 정적 파일 루트 경로
        ''' 
        Public ReadOnly Property RootPath As String
            Get
                Return _rootPath
            End Get
        End Property
        ''' 
        ''' StaticFileServer 생성자
        ''' 
        ''' 정적 파일을 서빙할 루트 디렉토리 경로
        ''' 사용할 포트 번호 (기본값: 58123)
        Public Sub New(rootPath As String, Optional port As Integer = 58123)
            If String.IsNullOrEmpty(rootPath) Then
                Throw New ArgumentException("rootPath는 비어있을 수 없습니다.", "rootPath")
            End If
            If Not Directory.Exists(rootPath) Then
                Directory.CreateDirectory(rootPath)
            End If
            _rootPath = Path.GetFullPath(rootPath)
            _baseUrl = String.Format("http://localhost:{0}", port)
        End Sub
        ''' 
        ''' 웹 서버 시작
        ''' 
        Public Sub Start()
            If _isRunning Then
                Throw New InvalidOperationException("서버가 이미 실행 중입니다.")
            End If
            Try
                ' OWIN 서버 시작
                _webApp = WebApp.Start(Of Startup)(_baseUrl)
                _isRunning = True
                ' 루트 경로를 Startup에서 접근할 수 있도록 설정
                Startup.RootPath = _rootPath
                Console.WriteLine("웹 서버 시작: {0}", _baseUrl)
                Console.WriteLine("루트 경로: {0}", _rootPath)
            Catch ex As Exception
                _isRunning = False
                Throw New Exception("웹 서버 시작 실패: " & ex.Message, ex)
            End Try
        End Sub
        ''' 
        ''' 웹 서버 중지
        ''' 
        Public Sub [Stop]()
            If Not _isRunning Then
                Return
            End If
            Try
                If _webApp IsNot Nothing Then
                    _webApp.Dispose()
                    _webApp = Nothing
                End If
                _isRunning = False
                Console.WriteLine("웹 서버 중지됨")
            Catch ex As Exception
                Throw New Exception("웹 서버 중지 실패: " & ex.Message, ex)
            End Try
        End Sub
        ''' 
        ''' 리소스 해제
        ''' 
        Public Sub Dispose() Implements IDisposable.Dispose
            [Stop]()
        End Sub
        ''' 
        ''' 특정 파일의 전체 URL 반환
        ''' 
        ''' 상대 경로 (예: "index.html" 또는 "images/logo.png")
        ''' 전체 URL
        Public Function GetFileUrl(relativePath As String) As String
            If String.IsNullOrEmpty(relativePath) Then
                Return _baseUrl & "/"
            End If
            ' 경로 정규화
            Dim normalizedPath As String = relativePath.Replace("\", "/")
            If Not normalizedPath.StartsWith("/") Then
                normalizedPath = "/" & normalizedPath
            End If
            Return _baseUrl & normalizedPath
        End Function
        ''' 
        ''' 브라우저에서 루트 URL 열기
        ''' 
        Public Sub OpenInBrowser()
            If Not _isRunning Then
                Throw New InvalidOperationException("서버가 실행 중이 아닙니다.")
            End If
            Try
                System.Diagnostics.Process.Start(_baseUrl)
            Catch ex As Exception
                Throw New Exception("브라우저 열기 실패: " & ex.Message, ex)
            End Try
        End Sub
        ''' 
        ''' 특정 파일을 브라우저에서 열기
        ''' 
        ''' 상대 경로
        Public Sub OpenFileInBrowser(relativePath As String)
            If Not _isRunning Then
                Throw New InvalidOperationException("서버가 실행 중이 아닙니다.")
            End If
            Try
                Dim url As String = GetFileUrl(relativePath)
                System.Diagnostics.Process.Start(url)
            Catch ex As Exception
                Throw New Exception("브라우저 열기 실패: " & ex.Message, ex)
            End Try
        End Sub
    End Class
End Namespace