Imports System.Data
Imports System.IO
Imports AppVariable
Imports System.Net



Partial Class download_uc_download
    Inherits System.Web.UI.UserControl

#Region "********************** プロパティ **********************"

    Private _Menu As String = ""
    Private _Category As String = ""
    Private _user As LoginUser
    Private DBServerAuthUserId As String = ConfigurationManager.AppSettings("WebDavAuthUserId").ToString()
    Private DBServerAuthUserPass As String = ConfigurationManager.AppSettings("WebDavAuthUserPass").ToString()

    Public Property Menu() As String
        Get
            Return _Menu
        End Get
        Set(ByVal value As String)
            _Menu = value
        End Set
    End Property

    Public Property Category() As String
        Get
            Return _Category
        End Get
        Set(ByVal value As String)
            _Category = value
        End Set
    End Property

#End Region

#Region "******************** ページイベント ********************"
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then

            _user = Session(S_COM_LoginUser)

            BindFilesToListView(_user)
        End If
    End Sub

#End Region

#Region "***************** コントロールイベント *****************"

    Protected Sub lsv_List_ItemDataBound(sender As Object, e As ListViewItemEventArgs) Handles lsv_List.ItemDataBound
        If e.Item.ItemType = ListViewItemType.DataItem Then
            Dim dataItem As DataRowView = DirectCast(e.Item.DataItem, DataRowView)

            'ファイルの存在有無の確認
            Dim filePath As String = dataItem("閲覧用ファイルパス").ToString()

            If filePath.StartsWith("http://") OrElse filePath.StartsWith("https://") Then

                'URL仕様にパスを書き換え
                filePath = filePath.Replace("\", "/")

                ' URLの場合
                If Not UrlExists(filePath) Then
                    e.Item.Visible = False
                End If
            Else
                ' ローカルファイルの場合
                If Not File.Exists(filePath) Then
                    e.Item.Visible = False
                End If
            End If
        End If
    End Sub
    Protected Sub lsv_List_ItemCommand(sender As Object, e As ListViewCommandEventArgs) Handles lsv_List.ItemCommand

        If e.CommandName = "Download" Then
            Dim filePath As String = e.CommandArgument.ToString()
            Dim fileName As String = Path.GetFileName(filePath)

            ' URLの場合
            If filePath.StartsWith("http://") OrElse filePath.StartsWith("https://") Then
                filePath = filePath.Replace("\", "/")
                DownloadFromUrl(filePath)
            Else
                'ローカルファイルパスの場合
                DownloadLocalFile(filePath)
            End If
        End If
    End Sub

#End Region

#Region "******************* Sub及びFunction ********************"

    Private Sub BindFilesToListView(user As LoginUser)

        Using spm As New StoredProcedureManager("DL_DOWNLOAD_SELECT")
            spm.AddPrmIn("@MENU名", Data.SqlDbType.VarChar, 50, _Menu)
            spm.AddPrmIn("@カテゴリ名", Data.SqlDbType.VarChar, 50, _Category)
            spm.AddPrmIn("@学園CD", Data.SqlDbType.VarChar, 20, user.学園CD)

            spm.Fill()

            Dim dt = spm.ds.Tables(0)
            lsv_List.DataSource = dt
            lsv_List.DataBind()
        End Using
    End Sub

    Private Sub DownloadLocalFile(filePath As String)
        Dim fileName As String = Path.GetFileName(filePath)
        If File.Exists(filePath) Then
            Response.ContentType = "application/octet-stream"
            Response.AppendHeader("Content-Disposition", String.Format("attachment; filename=""{0}""", fileName))
            Response.TransmitFile(filePath)
            Response.End()
        Else
            Response.Write("<script>alert('指定されたファイルが存在しません。');</script>")
        End If
    End Sub

    Private Sub DownloadFromUrl(url As String)
        Try
            ' ファイルをダウンロード
            Dim fileName As String = Path.GetFileName(url)
            ' レスポンスヘッダーを設定
            Response.Clear()
            Response.Buffer = False
            Response.ContentType = "application/octet-stream"
            Response.AddHeader("Content-Disposition", "attachment; filename=""" & fileName & """")

            Using client As New WebClient()
                ' 認証情報を設定
                Dim username As String = DBServerAuthUserId
                Dim password As String = DBServerAuthUserPass
                Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(username & ":" & password))
                client.Headers("Authorization") = "Basic " & credentials
                Dim fileData As Byte() = client.DownloadData(url)

                Response.AddHeader("Content-Length", fileData.Length.ToString())
                Response.OutputStream.Write(fileData, 0, fileData.Length)

                Response.Flush()
                Response.Close()
            End Using
        Catch ex As WebException

            Dim errorResponse As HttpWebResponse = TryCast(ex.Response, HttpWebResponse)
            If errorResponse IsNot Nothing Then
                Select Case errorResponse.StatusCode
                    Case HttpStatusCode.Unauthorized
                        Response.Write("<script>alert('認証に失敗しました。ユーザーIDとパスワードを確認してください。');</script>")
                    Case HttpStatusCode.NotFound
                        Response.Write("<script>alert('指定されたファイルが見つかりません。');</script>")
                    Case Else
                        Response.Write(String.Format("<script>alert('ファイルのダウンロードに失敗しました: {0}');</script>", ex.Message))
                End Select
            Else
                Response.Write(String.Format("<script>alert('ネットワークエラーが発生しました: {0}');</script>", ex.Message))
            End If
        Catch ex As Exception
            ' その他の例外処理
            Response.Write(String.Format("<script>alert('エラーが発生しました: {0}');</script>", ex.Message))
        End Try
    End Sub

    Private Function UrlExists(url As String) As Boolean
        Try
            Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
            request.Method = "HEAD"
            request.Timeout = 5000 ' 5秒のタイムアウト

            Dim username As String = DBServerAuthUserId
            Dim password As String = DBServerAuthUserPass
            Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(username & ":" & password))
            request.Headers("Authorization") = "Basic " & credentials

            Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
                Return (response.StatusCode = HttpStatusCode.OK)
            End Using

        Catch ex As WebException
            ' 404 Not Found や他のエラーの場合
            Dim errorResponse As HttpWebResponse = TryCast(ex.Response, HttpWebResponse)
            If errorResponse IsNot Nothing AndAlso errorResponse.StatusCode = HttpStatusCode.Unauthorized Then

            End If
            Return False
        Catch ex As Exception
            Return False
        End Try
    End Function

#End Region

End Class
