Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Linq

Namespace Nexamas.UI.Modules

    ''' <summary>
    ''' Immutable internal module descriptor for Nexamas UI-owned module registration.
    ''' </summary>
    Friend NotInheritable Class MASModuleDescriptor

        Private ReadOnly _contributions As MASModuleContribution()

        Friend Sub New(moduleId As String,
                       displayName As String,
                       ownerSystem As String,
                       Optional version As String = "",
                       Optional contributions As IEnumerable(Of MASModuleContribution) = Nothing)
            Me.ModuleId = MASModuleContribution.NormalizeId(moduleId)
            Me.DisplayName = MASModuleContribution.NormalizeText(displayName)
            Me.OwnerSystem = MASModuleContribution.NormalizeText(ownerSystem)
            Me.Version = MASModuleContribution.NormalizeText(version)
            _contributions = NormalizeContributions(contributions)
        End Sub

        Friend ReadOnly Property ModuleId As String
        Friend ReadOnly Property DisplayName As String
        Friend ReadOnly Property OwnerSystem As String
        Friend ReadOnly Property Version As String

        Friend ReadOnly Property Contributions As MASModuleContribution()
            Get
                Return DirectCast(_contributions.Clone(), MASModuleContribution())
            End Get
        End Property

        Friend ReadOnly Property ContributionCount As Integer
            Get
                Return _contributions.Length
            End Get
        End Property

        Friend ReadOnly Property IsValid As Boolean
            Get
                Return ModuleId.Length > 0 AndAlso DisplayName.Length > 0 AndAlso OwnerSystem.Length > 0
            End Get
        End Property

        Friend ReadOnly Property HasInternallyConsistentContributions As Boolean
            Get
                Return _contributions.All(Function(contribution) contribution IsNot Nothing AndAlso
                                                                    String.Equals(contribution.ModuleId, ModuleId, StringComparison.OrdinalIgnoreCase) AndAlso
                                                                    contribution.IsValid)
            End Get
        End Property

        Friend Function HasContribution(kind As MASModuleContributionKind) As Boolean
            Return _contributions.Any(Function(contribution) contribution.Kind = kind)
        End Function

        Friend Function WithContributions(contributions As IEnumerable(Of MASModuleContribution)) As MASModuleDescriptor
            Return New MASModuleDescriptor(ModuleId, DisplayName, OwnerSystem, Version, contributions)
        End Function

        Private Shared Function NormalizeContributions(values As IEnumerable(Of MASModuleContribution)) As MASModuleContribution()
            If values Is Nothing Then Return New MASModuleContribution() {}

            Return values.Where(Function(value) value IsNot Nothing).ToArray()
        End Function

    End Class

End Namespace
