Option Strict On
Option Explicit On

Imports System.Linq

Namespace Nexamas.UI.DataBinding

    ''' <summary>
    ''' Immutable snapshot proving simple application binding coverage without scanning controls or rendering UI.
    ''' </summary>
    Friend NotInheritable Class MASViewModelBindingSnapshot

        Private ReadOnly _bindings As MASViewModelBindingRecord()
        Private ReadOnly _commands As MASViewModelCommandBindingRecord()

        Friend Sub New(sourceName As String,
                       bindings As MASViewModelBindingRecord(),
                       commands As MASViewModelCommandBindingRecord(),
                       Optional lifecycle As MASViewModelBindingLifecycleSnapshot = Nothing)
            Me.SourceName = If(sourceName, String.Empty).Trim()
            _bindings = If(bindings, New MASViewModelBindingRecord() {}).Where(Function(binding) binding IsNot Nothing).ToArray()
            _commands = If(commands, New MASViewModelCommandBindingRecord() {}).Where(Function(command) command IsNot Nothing).ToArray()
            Me.Lifecycle = lifecycle
        End Sub

        Friend ReadOnly Property SourceName As String
        Friend ReadOnly Property Lifecycle As MASViewModelBindingLifecycleSnapshot

        Friend ReadOnly Property Bindings As MASViewModelBindingRecord()
            Get
                Return DirectCast(_bindings.Clone(), MASViewModelBindingRecord())
            End Get
        End Property

        Friend ReadOnly Property Commands As MASViewModelCommandBindingRecord()
            Get
                Return DirectCast(_commands.Clone(), MASViewModelCommandBindingRecord())
            End Get
        End Property

        Friend ReadOnly Property BindingCount As Integer
            Get
                Return _bindings.Length
            End Get
        End Property

        Friend ReadOnly Property CommandBindingCount As Integer
            Get
                Return _commands.Length
            End Get
        End Property

        Friend ReadOnly Property ReadyBindingCount As Integer
            Get
                Return _bindings.Where(Function(binding) binding.IsReady).Count()
            End Get
        End Property

        Friend ReadOnly Property ReadyCommandBindingCount As Integer
            Get
                Return _commands.Where(Function(command) command.IsReady).Count()
            End Get
        End Property

        Friend ReadOnly Property HasTextBinding As Boolean
            Get
                Return HasReadyBinding(MASViewModelBindingKind.Text)
            End Get
        End Property

        Friend ReadOnly Property HasEnabledBinding As Boolean
            Get
                Return HasReadyBinding(MASViewModelBindingKind.Enabled)
            End Get
        End Property

        Friend ReadOnly Property HasSelectionBinding As Boolean
            Get
                Return HasReadyBinding(MASViewModelBindingKind.Selection)
            End Get
        End Property

        Friend ReadOnly Property HasListBinding As Boolean
            Get
                Return HasReadyBinding(MASViewModelBindingKind.List)
            End Get
        End Property

        Friend ReadOnly Property HasCommandBinding As Boolean
            Get
                Return _commands.Any(Function(command) command.IsReady)
            End Get
        End Property

        Friend ReadOnly Property HasLifecycleHardenedCommandBinding As Boolean
            Get
                Return _commands.Any(Function(command) command.IsLifecycleHardened)
            End Get
        End Property

        Friend ReadOnly Property HasNoFailedBindings As Boolean
            Get
                Return _bindings.All(Function(binding) binding.Status = MASViewModelBindingStatus.Ready) AndAlso
                       _commands.All(Function(command) command.Status = MASViewModelBindingStatus.Ready)
            End Get
        End Property

        Friend ReadOnly Property ReadyForSimpleApplicationBinding As Boolean
            Get
                Return HasNoFailedBindings AndAlso
                       HasTextBinding AndAlso
                       HasEnabledBinding AndAlso
                       HasSelectionBinding AndAlso
                       HasListBinding AndAlso
                       HasCommandBinding
            End Get
        End Property

        Friend ReadOnly Property ReadyForLifecycleHardenedBinding As Boolean
            Get
                Return ReadyForSimpleApplicationBinding AndAlso
                       Lifecycle IsNot Nothing AndAlso
                       Lifecycle.ReadyForLifecycleHardening AndAlso
                       HasLifecycleHardenedCommandBinding
            End Get
        End Property

        Friend Function HasReadyBinding(kind As MASViewModelBindingKind) As Boolean
            Return _bindings.Any(Function(binding) binding.Kind = kind AndAlso binding.IsReady)
        End Function

    End Class

End Namespace
