import 'package:core/utils/app_logger.dart'; import 'package:core/utils/platform_info.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:fk_user_agent/fk_user_agent.dart'; import 'package:flutter/foundation.dart'; import 'package:package_info_plus/package_info_plus.dart'; class ApplicationManager { ApplicationManager._internal(); static final ApplicationManager _instance = ApplicationManager._internal(); factory ApplicationManager() => _instance; @visibleForTesting static DeviceInfoPlugin? debugDeviceInfoOverride; DeviceInfoPlugin? _deviceInfoCache; DeviceInfoPlugin get _deviceInfo => debugDeviceInfoOverride ?? (_deviceInfoCache ??= DeviceInfoPlugin()); PackageInfo? _packageInfoCache; String? _versionCache; String? _cachedWebUserAgent; String? _cachedMobileUserAgent; bool _isMobileUserAgentInitialized = false; @visibleForTesting void clearCache() { _packageInfoCache = null; _versionCache = null; _cachedWebUserAgent = null; _cachedMobileUserAgent = null; _isMobileUserAgentInitialized = false; _deviceInfoCache = null; } Future getPackageInfo() async { if (_packageInfoCache != null) { return _packageInfoCache!; } final info = await PackageInfo.fromPlatform(); _packageInfoCache = info; log('ApplicationManager:getPackageInfo -> cached: $info'); return info; } Future getAppVersion() async { if (_versionCache != null) { return _versionCache!; } try { final version = (await getPackageInfo()).version; _versionCache = version; log('ApplicationManager:getAppVersion -> cached: $version'); return version; } catch (e) { logWarning('ApplicationManager:getAppVersion failed, Exception = $e'); return ''; } } Future initUserAgent() async { if (!PlatformInfo.isMobile) return; try { await FkUserAgent.init(); _isMobileUserAgentInitialized = true; _cachedMobileUserAgent = null; log('ApplicationManager:initUserAgent -> initialized'); } catch (e) { logWarning('ApplicationManager:initUserAgent failed, Exception $e'); } } Future releaseUserAgent() async { if (!PlatformInfo.isMobile) return; try { FkUserAgent.release(); _isMobileUserAgentInitialized = false; _cachedMobileUserAgent = null; log('ApplicationManager:releaseUserAgent -> released & cache cleared'); } catch (e) { logWarning('ApplicationManager:releaseUserAgent failed, Exception $e'); } } Future getUserAgent() async { try { if (PlatformInfo.isWeb) { return _getWebUserAgent(); } if (PlatformInfo.isMobile) { return _getMobileUserAgent(); } return ''; } catch (e) { logWarning('ApplicationManager:getUserAgent failed'); return ''; } } Future _getWebUserAgent() async { if (_cachedWebUserAgent != null) { return _cachedWebUserAgent!; } WebBrowserInfo webInfo; try { webInfo = await _deviceInfo.webBrowserInfo; } catch (e) { logWarning('ApplicationManager:_getWebUserAgent failed, Exception $e'); return ''; } final userAgent = webInfo.userAgent ?? ''; _cachedWebUserAgent = userAgent; log('ApplicationManager:_getWebUserAgent -> cached'); return userAgent; } Future _getMobileUserAgent() async { if (!_isMobileUserAgentInitialized) { logWarning( 'ApplicationManager:_getMobileUserAgent called before initUserAgent', ); return ''; } if (_cachedMobileUserAgent != null) { return _cachedMobileUserAgent!; } final userAgent = FkUserAgent.userAgent; if (userAgent == null || userAgent.isEmpty) { return ''; } _cachedMobileUserAgent = userAgent; log('ApplicationManager:_getMobileUserAgent -> cached'); return userAgent; } Future generateApplicationUserAgent() async { final version = await getAppVersion(); final userAgent = await getUserAgent(); return 'Workavia-Mail/$version $userAgent'.trim(); } }