Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only snapshot for a product control's hosted-content contract. It is
    ''' an evidence object used by gates and does not expose hosted controls.
    ''' </summary>
    Friend NotInheritable Class MASHostedContentContractSnapshot

        Private ReadOnly _slots As IReadOnlyList(Of MASHostedContentSlotSnapshot)

        Friend Sub New(ownerComponentId As String,
                       lifecycleGeneration As Integer,
                       slots As IEnumerable(Of MASHostedContentSlotSnapshot))
            Me.OwnerComponentId = Normalize(ownerComponentId)
            Me.LifecycleGeneration = Math.Max(0, lifecycleGeneration)

            Dim copy As New List(Of MASHostedContentSlotSnapshot)()
            If slots IsNot Nothing Then
                For Each slot As MASHostedContentSlotSnapshot In slots
                    If slot IsNot Nothing Then copy.Add(slot)
                Next
            End If
            _slots = New ReadOnlyCollection(Of MASHostedContentSlotSnapshot)(copy.ToArray())
        End Sub

        Friend ReadOnly Property OwnerComponentId As String
        Friend ReadOnly Property LifecycleGeneration As Integer

        Friend ReadOnly Property Slots As IReadOnlyList(Of MASHostedContentSlotSnapshot)
            Get
                Return _slots
            End Get
        End Property

        Friend ReadOnly Property SlotCount As Integer
            Get
                Return _slots.Count
            End Get
        End Property

        Friend ReadOnly Property HostedSlotCount As Integer
            Get
                Dim count As Integer = 0
                For Each slot As MASHostedContentSlotSnapshot In _slots
                    If slot IsNot Nothing AndAlso slot.IsHosted Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property IsStructurallyValid As Boolean
            Get
                If OwnerComponentId.Length = 0 Then Return False
                Dim keys As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
                For Each slot As MASHostedContentSlotSnapshot In _slots
                    If slot Is Nothing OrElse Not slot.IsStructurallyValid Then Return False
                    If Not keys.Add(slot.SlotKey) Then Return False
                Next
                Return True
            End Get
        End Property

        Friend Function HasHostedSlot(slotKey As String) As Boolean
            Dim key As String = Normalize(slotKey)
            If key.Length = 0 Then Return False
            For Each slot As MASHostedContentSlotSnapshot In _slots
                If slot IsNot Nothing AndAlso slot.IsHosted AndAlso String.Equals(slot.SlotKey, key, StringComparison.OrdinalIgnoreCase) Then Return True
            Next
            Return False
        End Function

        Friend Function HasVisibleHostedSlot(slotKey As String) As Boolean
            Dim key As String = Normalize(slotKey)
            If key.Length = 0 Then Return False
            For Each slot As MASHostedContentSlotSnapshot In _slots
                If slot IsNot Nothing AndAlso slot.IsHosted AndAlso slot.IsVisible AndAlso String.Equals(slot.SlotKey, key, StringComparison.OrdinalIgnoreCase) Then Return True
            Next
            Return False
        End Function

        Private Shared Function Normalize(value As String) As String
            If value Is Nothing Then Return String.Empty
            Return value.Trim()
        End Function

    End Class

End Namespace
