Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.IO

Namespace Nexamas.UI.FileSystem

    Friend NotInheritable Class FileSystemComputerRootBuilder

        Private ReadOnly _provider As IFileSystemProvider

        Friend Sub New()
            Me.New(New LocalFileSystemProvider())
        End Sub

        Friend Sub New(provider As IFileSystemProvider)
            _provider = If(provider, New LocalFileSystemProvider())
        End Sub

        Friend Function Build(includeSpecialFolders As Boolean,
                              includeDrives As Boolean) As FileSystemEntry

            Return New FileSystemEntry With {
                .Name = "This PC",
                .FullPath = String.Empty,
                .EntryType = FileSystemEntryType.Computer
            }
        End Function

        Friend Function BuildChildren(includeSpecialFolders As Boolean,
                              includeDrives As Boolean) As List(Of FileSystemEntry)

            Dim result As New List(Of FileSystemEntry)()

            If includeSpecialFolders Then
                AddSpecialFolderPath(result, "Desktop", Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), FileSystemEntryType.Desktop)
                AddSpecialFolderPath(result, "Documents", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), FileSystemEntryType.Documents)
                AddSpecialFolderPath(result, "Downloads", GetDownloadsPath(), FileSystemEntryType.Downloads)
                AddSpecialFolderPath(result, "User Profile", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), FileSystemEntryType.UserProfile)
            End If

            result.Add(New FileSystemEntry With {
        .Name = "This PC",
        .FullPath = String.Empty,
        .EntryType = FileSystemEntryType.Computer
    })

            If includeDrives Then
                Try
                    Dim drives As List(Of FileSystemEntry) = _provider.GetRoots()

                    If drives IsNot Nothing Then
                        result.AddRange(drives)
                    End If
                Catch masCaughtException1 As Exception
                    Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowFileSystemBoundary(masCaughtException1)
                End Try
            End If

            result.Add(New FileSystemEntry With {
        .Name = "Network",
        .FullPath = String.Empty,
        .EntryType = FileSystemEntryType.Network
    })

            result.Add(New FileSystemEntry With {
        .Name = "Control Panel",
        .FullPath = String.Empty,
        .EntryType = FileSystemEntryType.ControlPanel
    })

            result.Add(New FileSystemEntry With {
        .Name = "Recycle Bin",
        .FullPath = String.Empty,
        .EntryType = FileSystemEntryType.RecycleBin
    })

            Return result
        End Function

        Private Shared Sub AddSpecialFolderPath(result As List(Of FileSystemEntry),
                                                displayName As String,
                                                path As String,
                                                entryType As FileSystemEntryType)

            If result Is Nothing Then Return
            If String.IsNullOrWhiteSpace(path) Then Return

            result.Add(New FileSystemEntry With {
                .Name = If(displayName, String.Empty),
                .FullPath = path,
                .EntryType = entryType
            })
        End Sub

        Private Shared Function GetDownloadsPath() As String
            Try
                Dim userProfile As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
                If String.IsNullOrWhiteSpace(userProfile) Then Return String.Empty
                Return Path.Combine(userProfile, "Downloads")
            Catch masCaughtException2 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowFileSystemBoundary(masCaughtException2)
                Return String.Empty
            End Try
        End Function

    End Class

End Namespace
