"""EVTIME-01: Event-only fallback; never repair or relabel the source timeline."""

REASONS = frozenset(('RTP_TIMESTAMP_BACKWARD', 'SSRC_CHANGED', 'RTP_CLOCK_RATE_CHANGED'))
MAX_MS = 2**53 - 1


def positive_ms(value):
    return type(value) is int and 0 < value <= MAX_MS


def valid_reason(value):
    return (type(value) is str and bool(value) and
            len(value.split(',')) == len(set(value.split(','))) and
            set(value.split(',')) <= REASONS)


def validate_clock_fault(value):
    reason = value.invalidation_reason
    if reason is None:
        if value.invalidated_at_wall_ms is not None or type(value.invalidated_frames) is not int or value.invalidated_frames != 0:
            raise ValueError('Invalid private clock diagnostic.')
    elif (not valid_reason(reason) or not positive_ms(value.invalidated_at_wall_ms) or
          type(value.invalidated_frames) is not int or value.invalidated_frames < 1 or
          value.source_time_wall_ms is not None or value.sync_status not in ('RAW_ONLY', 'UNAVAILABLE')):
        raise ValueError('Invalid private clock invalidation.')


def event_diagnostic(frame, provider_key):
    value = frame.frame_time
    if value is None or not value.invalidation_reason:
        return None
    validate_clock_fault(value)
    if (value.time_source != 'EXTERNAL_ANCHOR_RTP_ZERO' or
            not positive_ms(value.anchor_wall_time_ms) or value.anchor_rtp_timestamp != 0 or
            provider_key not in ('pose', 'medium', 'fire', 'crowd')):
        return None
    return dict(source='AI_WALL_FALLBACK', reason=value.invalidation_reason,
                invalidatedAtWallMs=value.invalidated_at_wall_ms,
                invalidatedFrames=value.invalidated_frames, cameraId=str(frame.source_id),
                providerKey=provider_key, runId=frame.run_id, runGeneration=frame.run_generation)


def fallback_time(event):
    """Only new admissions carrying a run-bound diagnostic may bypass BLOCKED_TIME."""
    diagnostic = event.get('eventTimeFallback')
    timing = event.get('frameTime') or {}
    wall = event.get('aiRecordedAtWallMs')
    if not isinstance(diagnostic, dict) or not positive_ms(wall):
        return None
    if (diagnostic.get('source') != 'AI_WALL_FALLBACK' or
            not valid_reason(diagnostic.get('reason')) or
            not positive_ms(diagnostic.get('invalidatedAtWallMs')) or
            type(diagnostic.get('invalidatedFrames')) is not int or diagnostic['invalidatedFrames'] < 1 or
            diagnostic.get('cameraId') != str(event.get('cameraId')) or
            diagnostic.get('runId') != event.get('runId') or not diagnostic.get('runId') or
            type(diagnostic.get('runGeneration')) is not int or diagnostic['runGeneration'] < 1 or
            diagnostic['runGeneration'] != event.get('runGeneration') or
            diagnostic.get('providerKey') not in ('pose', 'medium', 'fire', 'crowd') or
            timing.get('timeSource') != 'EXTERNAL_ANCHOR_RTP_ZERO' or
            not positive_ms(timing.get('startWallTimeMs')) or timing.get('anchorRtpTimestamp') != 0 or
            timing.get('syncStatus') not in ('RAW_ONLY', 'UNAVAILABLE') or
            timing.get('detectedAtWallMs') is not None):
        return None
    return wall
