Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Certification

    ''' <summary>
    ''' Immutable aggregate report produced by the Quality Orchestrator.
    ''' </summary>
    ''' <remarks>
    ''' This report is the central internal truth surface for lightweight certification gates. It records
    ''' gate outcomes and summary facts only; it does not expose runtime telemetry or mutable proof state.
    ''' </remarks>
    Friend NotInheritable Class MASQualityReport
        Private ReadOnly _gateResults As IReadOnlyList(Of MASQualityGateResult)
        Private ReadOnly _proofMatrix As MASCertificationProofMatrix

        Friend Sub New(runId As String,
                       createdUtc As DateTime,
                       gateResults As IEnumerable(Of MASQualityGateResult))
            Me.RunId = Normalize(runId)
            Me.CreatedUtc = DateTime.SpecifyKind(createdUtc, DateTimeKind.Utc)
            _gateResults = New ReadOnlyCollection(Of MASQualityGateResult)(NormalizeGateResults(gateResults))
            _proofMatrix = MASCertificationProofMatrix.SourceOnly(ResolveStatusFromGateResults(_gateResults))
        End Sub

        Friend ReadOnly Property RunId As String
        Friend ReadOnly Property CreatedUtc As DateTime

        Friend ReadOnly Property ProofMatrix As MASCertificationProofMatrix
            Get
                Return _proofMatrix
            End Get
        End Property

        Friend ReadOnly Property GateResults As IReadOnlyList(Of MASQualityGateResult)
            Get
                Return _gateResults
            End Get
        End Property

        Friend ReadOnly Property GateCount As Integer
            Get
                Return GateResults.Count
            End Get
        End Property

        Friend ReadOnly Property PassedGateCount As Integer
            Get
                Dim count As Integer = 0
                For Each result As MASQualityGateResult In GateResults
                    If result IsNot Nothing AndAlso result.Status = MASQualityGateStatus.Passed Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property MonitoredGateCount As Integer
            Get
                Dim count As Integer = 0
                For Each result As MASQualityGateResult In GateResults
                    If result IsNot Nothing AndAlso (result.Status = MASQualityGateStatus.PassedWithWarnings OrElse result.Status = MASQualityGateStatus.Skipped) Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property BlockingGateCount As Integer
            Get
                Dim count As Integer = 0
                For Each result As MASQualityGateResult In GateResults
                    If result Is Nothing OrElse result.IsBlocking OrElse result.Status = MASQualityGateStatus.Failed Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property TotalErrorCount As Integer
            Get
                Dim count As Integer = 0
                For Each result As MASQualityGateResult In GateResults
                    If result IsNot Nothing Then count += result.ErrorCount
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property TotalWarningCount As Integer
            Get
                Dim count As Integer = 0
                For Each result As MASQualityGateResult In GateResults
                    If result IsNot Nothing Then count += result.WarningCount
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property HasBlockingGates As Boolean
            Get
                Return BlockingGateCount > 0
            End Get
        End Property

        Friend ReadOnly Property Status As NexamasUICertificationStatus
            Get
                Return ResolveStatusFromGateResults(GateResults)
            End Get
        End Property

        Friend ReadOnly Property Summary As String
            Get
                If GateCount = 0 Then Return "Quality Orchestrator produced no gate results."

                Return "Quality Orchestrator ran " & GateCount.ToString(CultureInfo.InvariantCulture) &
                       " gate(s): " & PassedGateCount.ToString(CultureInfo.InvariantCulture) &
                       " passed, " & MonitoredGateCount.ToString(CultureInfo.InvariantCulture) &
                       " monitored, " & BlockingGateCount.ToString(CultureInfo.InvariantCulture) &
                       " blocking."
            End Get
        End Property

        Friend Function FindByCertificationSystemKey(systemKey As String) As IReadOnlyList(Of MASQualityGateResult)
            Dim normalizedKey As String = Normalize(systemKey)
            Dim matches As New List(Of MASQualityGateResult)()
            If normalizedKey.Length = 0 Then Return matches

            For Each result As MASQualityGateResult In GateResults
                If result IsNot Nothing AndAlso String.Equals(result.CertificationSystemKey, normalizedKey, StringComparison.OrdinalIgnoreCase) Then
                    matches.Add(result)
                End If
            Next

            Return New ReadOnlyCollection(Of MASQualityGateResult)(matches)
        End Function

        Friend Function CreateProblemDetails() As IReadOnlyList(Of String)
            Dim details As New List(Of String)()
            For Each result As MASQualityGateResult In GateResults
                If result Is Nothing OrElse Not result.HasProblem Then Continue For
                details.Add(result.DisplayName & ": " & result.Summary)
                For Each detail As String In result.Details
                    details.Add("  - " & detail)
                Next
            Next
            Return New ReadOnlyCollection(Of String)(details)
        End Function

        Private Shared Function ResolveStatusFromGateResults(gateResults As IReadOnlyList(Of MASQualityGateResult)) As NexamasUICertificationStatus
            If gateResults Is Nothing OrElse gateResults.Count = 0 Then Return NexamasUICertificationStatus.IncompleteGovernance

            Dim monitored As Boolean = False
            For Each result As MASQualityGateResult In gateResults
                If result Is Nothing OrElse result.IsBlocking OrElse result.Status = MASQualityGateStatus.Failed Then Return NexamasUICertificationStatus.Blocked
                If result.Status = MASQualityGateStatus.PassedWithWarnings OrElse result.Status = MASQualityGateStatus.Skipped Then monitored = True
            Next

            If monitored Then Return NexamasUICertificationStatus.CertifiedWithMonitoring
            Return NexamasUICertificationStatus.Certified
        End Function

        Private Shared Function NormalizeGateResults(gateResults As IEnumerable(Of MASQualityGateResult)) As List(Of MASQualityGateResult)
            Dim result As New List(Of MASQualityGateResult)()
            If gateResults Is Nothing Then Return result

            For Each gateResult As MASQualityGateResult In gateResults
                If gateResult IsNot Nothing Then result.Add(gateResult)
            Next

            Return result
        End Function

        Private Shared Function Normalize(value As String) As String
            Return If(value, String.Empty).Trim()
        End Function
    End Class

End Namespace
