Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.DataBinding

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only proof that MASPivotTable can project a stable-keyed source into
    ''' row/column groups, aggregate values, keep drilldown evidence, expose an
    ''' export snapshot, and refresh when the source changes.
    ''' </summary>
    Friend NotInheritable Class MASPivotTableSourceProjectionGate
        Private Sub New()
        End Sub

        Friend Shared Function Passes() As Boolean
            Try
                If Not MASPivotTablePolicy.HasPivotSourceProjectionPath() Then Return False
                If Not MASPivotTablePolicy.HasAggregationEnginePath() Then Return False
                If Not MASPivotTablePolicy.HasDrilldownSnapshotPath() Then Return False

                Dim rows As New List(Of Object) From {
                    MASPivotSourceRecord.Create("North", "Q1", 10D),
                    MASPivotSourceRecord.Create("North", "Q1", 5D),
                    MASPivotSourceRecord.Create("North", "Q2", 20D),
                    MASPivotSourceRecord.Create("South", "Q1", 7D)
                }
                Dim source As MASListItemsSource = MASListItemsSource.FromEnumerable(rows, AddressOf ResolveProbeKey)
                Dim definition As MASPivotSourceDefinition = MASPivotSourceDefinition.Create("row", "column", "value", MASPivotAggregateKind.Sum)
                Dim pivot As MASPivotTable = MASPivotTable.Create("Pivot source gate")
                pivot.SetPivotSource(source, definition, "MASPivotTableSourceProjectionGate")

                If Not pivot.HasPivotSource Then Return False
                If pivot.RowCount <> 2 Then Return False
                If pivot.ColumnCount <> 2 Then Return False
                If pivot.GetCellValue("North", "Q1") <> 15D Then Return False
                If pivot.GetRowTotal("North") <> 35D Then Return False
                If pivot.GetColumnTotal("Q1") <> 22D Then Return False
                If pivot.GrandTotal <> 42D Then Return False
                If pivot.GetCellDrilldown("North", "Q1").Count <> 2 Then Return False

                Dim exportSnapshot As MASPivotExportSnapshot = pivot.CreatePivotExportSnapshot()
                If exportSnapshot.Rows.Count <> 2 Then Return False
                If exportSnapshot.Columns.Count <> 2 Then Return False
                If exportSnapshot.Cells.Count <> 4 Then Return False
                If exportSnapshot.GrandTotal <> 42D Then Return False

                source.Add(MASPivotSourceRecord.Create("South", "Q2", 3D))
                If pivot.PivotSourceRevision <> source.Revision Then Return False
                If pivot.GetCellValue("South", "Q2") <> 3D Then Return False
                If pivot.GrandTotal <> 45D Then Return False

                Dim countPivot As MASPivotTable = MASPivotTable.Create("Count gate")
                countPivot.SetPivotSource(source, MASPivotSourceDefinition.Create("row", "column", String.Empty, MASPivotAggregateKind.Count), "Count projection")
                If countPivot.GetCellValue("North", "Q1") <> 2D Then Return False

                Dim averagePivot As MASPivotTable = MASPivotTable.Create("Average gate")
                averagePivot.SetPivotSource(source, MASPivotSourceDefinition.Create("row", "column", "value", MASPivotAggregateKind.Average), "Average projection")
                If averagePivot.GetCellValue("North", "Q1") <> 7.5D Then Return False

                Dim minPivot As MASPivotTable = MASPivotTable.Create("Minimum gate")
                minPivot.SetPivotSource(source, MASPivotSourceDefinition.Create("row", "column", "value", MASPivotAggregateKind.Minimum), "Minimum projection")
                If minPivot.GetCellValue("North", "Q1") <> 5D Then Return False

                Dim maxPivot As MASPivotTable = MASPivotTable.Create("Maximum gate")
                maxPivot.SetPivotSource(source, MASPivotSourceDefinition.Create("row", "column", "value", MASPivotAggregateKind.Maximum), "Maximum projection")
                If maxPivot.GetCellValue("North", "Q1") <> 10D Then Return False

                pivot.SetCellValue("North", "Q1", 100D)
                If pivot.HasPivotSource Then Return False
                If pivot.GetCellDrilldown("North", "Q1").Count <> 0 Then Return False

                Return True
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDiagnosticOnly(ex, "MASPivotTableSourceProjectionGate")
                Return False
            End Try
        End Function

        Private Shared Function ResolveProbeKey(item As Object) As String
            Dim record As MASPivotSourceRecord = TryCast(item, MASPivotSourceRecord)
            If record Is Nothing Then Return String.Empty
            Dim rowValue As Object = Nothing
            Dim columnValue As Object = Nothing
            Dim value As Object = Nothing
            record.TryGetField("row", rowValue)
            record.TryGetField("column", columnValue)
            record.TryGetField("value", value)
            Return Convert.ToString(rowValue, Globalization.CultureInfo.InvariantCulture) & ":" & Convert.ToString(columnValue, Globalization.CultureInfo.InvariantCulture) & ":" & Convert.ToString(value, Globalization.CultureInfo.InvariantCulture)
        End Function
    End Class

End Namespace
