initialise method

Future<void> initialise({
  1. Future<void> appRunner()?,
})

Initialises the observability stack based on configuration from ConfigService.

Reads system-monitoring-enabled (global kill switch) and system-observability-settings (provider selection + provider-specific config) from ConfigService to determine which provider to use.

If system-observability-settings is not configured in config-service, the manager enters legacy mode and reads the existing per-service flags (config_settings_monitoring_enabled, config_settings_analytics_enabled, config_settings_monitoring_trace_mode) to initialise Firebase services with the exact same behaviour as the old injector.dart.

appRunner is an optional callback (typically () async => runApp(MyApp())) that will be passed to SentryFlutter.init() when using the Sentry provider, ensuring Sentry captures errors from the moment the app starts. For Firebase, legacy mode, or 'none' providers, appRunner is called directly.

Implementation

Future<void> initialise({Future<void> Function()? appRunner}) async {
  if (_isInitialised) {
    logger.info(
        this, 'LittlefishObservabilityManager is already initialized.');
    return;
  }

  // Global kill switch - if disabled, skip all observability
  final isEnabled = configService.getBoolValue(
    key: 'system-monitoring-enabled',
    defaultValue: true,
  );

  if (!isEnabled) {
    logger.info(
      this,
      'Observability is globally disabled via system-monitoring-enabled.',
    );
    _activeProvider = 'none';
    _isInitialised = true;
    // Still run appRunner if provided, just without Sentry wrapping
    if (appRunner != null) await appRunner();
    return;
  }

  // 2. Settings detection - determine legacy vs new mode
  final rawSettings = configService.getObjectValue(
    key: 'system-observability-settings',
    defaultValue: _notConfiguredSentinel,
  );

  if (_isNotConfigured(rawSettings)) {
    // LEGACY MODE: Flag not present in config-service.
    // Use Firebase with existing per-service config flags.
    logger.info(
      this,
      'system-observability-settings not configured. '
      'Using legacy Firebase mode with existing config flags.',
    );
    _isLegacyMode = true;
    await _initialiseLegacyFirebase(appRunner: appRunner);
    _isInitialised = true;
    logger.info(
      this,
      'LittlefishObservabilityManager initialized. '
      'Provider: $_activeProvider (legacy mode)',
    );
    return;
  }

  // NEW MODE: Flag exists - proceed with provider selection
  _isLegacyMode = false;
  final Map<String, dynamic> observabilitySettings;
  if (rawSettings is Map<String, dynamic>) {
    observabilitySettings = rawSettings;
  } else {
    logger.warning(
      this,
      'system-observability-settings returned unexpected type '
      '(${rawSettings.runtimeType}), falling back to legacy Firebase.',
    );
    _isLegacyMode = true;
    await _initialiseLegacyFirebase(appRunner: appRunner);
    _isInitialised = true;
    return;
  }

  final provider = observabilitySettings['provider'] as String? ?? 'firebase';

  switch (provider) {
    case 'sentry':
      final sentryConfig =
          observabilitySettings['sentry'] as Map<String, dynamic>? ?? {};
      await _initialiseSentry(sentryConfig, appRunner: appRunner);
      break;
    case 'firebase':
      await _initialiseFirebase(observabilitySettings);
      if (appRunner != null) await appRunner();
      break;
    case 'none':
      logger.info(
        this,
        'Observability provider set to none - no services registered.',
      );
      _activeProvider = 'none';
      if (appRunner != null) await appRunner();
      break;
    default:
      logger.warning(
        this,
        'Unknown provider "$provider", falling back to legacy Firebase.',
      );
      _isLegacyMode = true;
      await _initialiseLegacyFirebase(appRunner: appRunner);
  }

  _isInitialised = true;
  logger.info(
    this,
    'LittlefishObservabilityManager initialized. '
    'Provider: $_activeProvider, Legacy: $_isLegacyMode',
  );
}