Imports System.Threading.Tasks
Imports System.Text
Imports System.Linq
Imports System.Collections.Generic
Imports System

Public Class DataService
    Private rnd As New Random()
    Shared _default As DataService

    Public Shared ReadOnly Property Instance() As DataService
        Get
            If _default Is Nothing Then
                _default = New DataService()
            End If

            Return _default
        End Get
    End Property

    Public Shared Function CreateHierarchicalData() As List(Of DataItem)
        Dim rnd As Random = Instance.rnd

        Dim years As New List(Of String)()
        Dim times As New List(Of List(Of String))() From {
            New List(Of String)() From {"Jan", "Feb", "Mar"},
            New List(Of String)() From {"Apr", "May", "June"},
            New List(Of String)() From {"Jul", "Aug", "Sep"},
            New List(Of String)() From {"Oct", "Nov", "Dec"}
            }

        Dim items As New List(Of DataItem)()
        Dim yearLen As Integer = Math.Max(CType(Math.Round(Math.Abs(5 - Instance.rnd.NextDouble() * 10)), Integer), 3)
        Dim currentYear As Integer = DateTime.Now.Year
        Dim j As Integer = yearLen
        While j > 0
            years.Add((currentYear - j).ToString())
            j -= 1
        End While
        Dim quarterAdded As Boolean = False

        years.ForEach(Sub(y)
                          Dim i As Object = years.IndexOf(y)
                          Dim addQuarter As Boolean = Instance.rnd.NextDouble() > 0.5
                          If Not quarterAdded AndAlso i = years.Count - 1 Then
                              addQuarter = True
                          End If
                          Dim year As New DataItem() With {
                              .Year = y
                          }
                          If addQuarter Then
                              quarterAdded = True
                              times.ForEach(Sub(q)
                                                Dim addMonth As Boolean = Instance.rnd.NextDouble() > 0.5
                                                Dim idx As Integer = times.IndexOf(q)
                                                Dim quar As String = "Q" + (idx + 1).ToString()
                                                Dim quarters As New DataItem() With {
                                                    .Year = y,
                                                    .Quarter = quar
                                                }
                                                If addMonth Then
                                                    q.ForEach(Sub(m)
                                                                  quarters.Items.Add(New DataItem() With {
                                                                      .Year = y,
                                                                      .Quarter = quar,
                                                                      .Month = m,
                                                                      .Value = rnd.[Next](20, 30)
                                                                  })

                                                              End Sub)
                                                Else
                                                    quarters.Value = rnd.[Next](80, 100)
                                                End If
                                                year.Items.Add(quarters)

                                            End Sub)
                          Else
                              year.Value = rnd.[Next](80, 100)
                          End If
                          items.Add(year)

                      End Sub)

        Return items
    End Function

    Public Shared Function CreateFlatData() As List(Of FlatDataItem)
        Dim rnd As Random = Instance.rnd
        Dim years As New List(Of String)()
        Dim times As New List(Of List(Of String))() From {
            New List(Of String)() From {"Jan", "Feb", "Mar"},
            New List(Of String)() From {"Apr", "May", "June"},
            New List(Of String)() From {"Jul", "Aug", "Sep"},
            New List(Of String)() From {"Oct", "Nov", "Dec"}
            }

        Dim items As New List(Of FlatDataItem)()
        Dim yearLen As Integer = Math.Max(CType(Math.Round(Math.Abs(5 - rnd.NextDouble() * 10)), Integer), 3)
        Dim currentYear As Integer = DateTime.Now.Year
        Dim j As Integer = yearLen
        While j > 0
            years.Add((currentYear - j).ToString())
            j -= 1
        End While
        Dim quarterAdded As Boolean = False
        years.ForEach(Sub(y)
                          Dim i As Object = years.IndexOf(y)
                          Dim addQuarter As Boolean = rnd.NextDouble() > 0.5
                          If Not quarterAdded AndAlso i = years.Count - 1 Then
                              addQuarter = True
                          End If
                          If addQuarter Then
                              quarterAdded = True
                              times.ForEach(Sub(q)
                                                Dim addMonth As Boolean = rnd.NextDouble() > 0.5
                                                Dim idx As Integer = times.IndexOf(q)
                                                Dim quar As String = "Q" + (idx + 1).ToString()
                                                If addMonth Then
                                                    q.ForEach(Sub(m)
                                                                  items.Add(New FlatDataItem() With {
                                                                      .Year = y,
                                                                      .Quarter = quar,
                                                                      .Month = m,
                                                                      .Value = rnd.[Next](30, 40)
                                                                  })

                                                              End Sub)
                                                Else
                                                    items.Add(New FlatDataItem() With {
                                                        .Year = y,
                                                        .Quarter = quar,
                                                        .Value = rnd.[Next](80, 100)
                                                    })
                                                End If

                                            End Sub)
                          Else
                              items.Add(New FlatDataItem() With {
                                  .Year = y.ToString(),
                                  .Value = rnd.[Next](80, 100)
                              })
                          End If

                      End Sub)

        Return items
    End Function
End Class