Option Strict On
Option Explicit On

Imports System
Imports System.Linq

Namespace Nexamas.UI.CommandActions

     ''' <summary>
     ''' Immutable audit snapshot for registered commands and their presentation bindings.
     ''' </summary>
    Friend NotInheritable Class MASCommandRegistrySnapshot

        Private ReadOnly _commands As MASCommandCatalogEntry()
        Private ReadOnly _bindings As MASCommandBindingRecord()

        Friend Sub New(commands As MASCommandCatalogEntry(),
                       bindings As MASCommandBindingRecord(),
                       sourceName As String)
            _commands = If(commands, New MASCommandCatalogEntry() {}).Where(Function(entry) entry IsNot Nothing).ToArray()
            _bindings = If(bindings, New MASCommandBindingRecord() {}).Where(Function(binding) binding IsNot Nothing).ToArray()
            Me.SourceName = If(sourceName, String.Empty)
        End Sub

        Friend ReadOnly Property SourceName As String

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

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

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

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

        Friend ReadOnly Property HasNoDuplicateCommandIds As Boolean
            Get
                Return _commands.Select(Function(entry) entry.CommandId).Distinct(StringComparer.OrdinalIgnoreCase).Count() = _commands.Length
            End Get
        End Property

        Friend ReadOnly Property HasExecutableCommands As Boolean
            Get
                Return _commands.Length > 0 AndAlso _commands.All(Function(entry) entry.ReadyForBinding)
            End Get
        End Property

        Friend ReadOnly Property HasButtonMenuShortcutToolbarCoverage As Boolean
            Get
                Return HasBinding(MASCommandBindingSurfaceKind.Button) AndAlso
                       HasBinding(MASCommandBindingSurfaceKind.Menu) AndAlso
                       HasBinding(MASCommandBindingSurfaceKind.Shortcut) AndAlso
                       HasBinding(MASCommandBindingSurfaceKind.Toolbar)
            End Get
        End Property

        Friend ReadOnly Property ReadyForCommandBarAndPalette As Boolean
            Get
                Return HasExecutableCommands AndAlso
                       HasNoDuplicateCommandIds AndAlso
                       HasButtonMenuShortcutToolbarCoverage
            End Get
        End Property

        Friend ReadOnly Property HasCommandBarCoverage As Boolean
            Get
                Return HasBinding(MASCommandBindingSurfaceKind.CommandBar)
            End Get
        End Property

        Friend ReadOnly Property ReadyForPremiumCommandBar As Boolean
            Get
                Return HasExecutableCommands AndAlso
                       HasNoDuplicateCommandIds AndAlso
                       HasCommandBarCoverage
            End Get
        End Property

        Friend ReadOnly Property HasCommandPaletteCoverage As Boolean
            Get
                Return HasBinding(MASCommandBindingSurfaceKind.CommandPalette)
            End Get
        End Property

        Friend ReadOnly Property ReadyForPremiumCommandPalette As Boolean
            Get
                Return HasExecutableCommands AndAlso
                       HasNoDuplicateCommandIds AndAlso
                       HasCommandPaletteCoverage
            End Get
        End Property


        Friend ReadOnly Property HasMenuBarCoverage As Boolean
            Get
                Return HasBinding(MASCommandBindingSurfaceKind.MenuBar)
            End Get
        End Property

        Friend ReadOnly Property ReadyForPremiumMenuBar As Boolean
            Get
                Return HasExecutableCommands AndAlso
                       HasNoDuplicateCommandIds AndAlso
                       HasMenuBarCoverage
            End Get
        End Property

        Friend Function HasBinding(kind As MASCommandBindingSurfaceKind) As Boolean
            Return _bindings.Any(Function(binding) binding.SurfaceKind = kind)
        End Function

    End Class

End Namespace
