Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Web
Imports System.Xml.Linq

Public NotInheritable Class Employees
    Private Sub New()
    End Sub
    Private Shared _dataset As DataSet
    Private Shared _countries As String()
    Private Shared _lockObj As New Object()

    Public Shared ReadOnly Property DataSet() As DataSet
        Get
            EnsureInit()
            Return _dataset
        End Get
    End Property

    Public Shared ReadOnly Property CountryNames() As String()
        Get
            EnsureInit()
            Return _countries
        End Get
    End Property

    Private Shared Sub EnsureInit()
        If _dataset Is Nothing Then
            SyncLock _lockObj
                If _dataset Is Nothing Then
                    InitDataSet()
                End If
            End SyncLock
        End If
    End Sub

    Private Shared Sub InitDataSet()
        _dataset = New DataSet()

        Dim doc = XElement.Load(HttpContext.Current.Server.MapPath("~/Content/nwind.xml"))
        For Each employee In doc.Elements("Employees")
            Dim country = employee.Element("Country").Value
            Dim table = GetEmployeesDataTable(country)
            Dim row = table.NewRow()
            row("Country") = country
            row("LastName") = employee.Element("LastName").Value
            row("FirstName") = employee.Element("FirstName").Value
            row("City") = employee.Element("City").Value
            row("Address") = employee.Element("Address").Value
            row("Notes") = employee.Element("Notes").Value
            table.Rows.Add(row)
        Next

        _countries = _dataset.Tables.OfType(Of DataTable)().[Select](Function(t) t.TableName).ToArray()
    End Sub

    Private Shared Function GetEmployeesDataTable(name As String) As DataTable
        If _dataset.Tables.Contains(name) Then
            Return _dataset.Tables(name)
        End If

        Dim table = CreateEmployeesDataTable(name)
        _dataset.Tables.Add(table)
        Return table
    End Function

    Private Shared Function CreateEmployeesDataTable(name As String) As DataTable
        Dim table = New DataTable(name)
        table.Columns.Add("LastName")
        table.Columns.Add("FirstName")
        table.Columns.Add("Country")
        table.Columns.Add("City")
        table.Columns.Add("Address")
        table.Columns.Add("Notes")
        Return table
    End Function
End Class
