content: import 'dart:convert';
  import 'dart:math';
  
  import 'package:flutter/foundation.dart';
  import 'package:flutter/services.dart';
  
  import 'package:flutter_secure_storage/flutter_secure_storage.dart';
  import 'package:matrix/matrix.dart';
  import 'package:shared_preferences/shared_preferences.dart';
  
  import 'package:fluffychat/config/setting_keys.dart';
  import 'package:fluffychat/l10n/l10n.dart';
  import 'package:fluffychat/utils/client_manager.dart';
  
  const _passwordStorageKey = 'database_password';
  
  Future<String?> getDatabaseCipher() async {
    String? password;
  
    try {
      const secureStorage = FlutterSecureStorage();
      final containsEncryptionKey =
          await secureStorage.read(key: _passwordStorageKey) != null;
      if (!containsEncryptionKey) {
        final rng = Random.secure();
        final list = Uint8List(32);
        list.setAll(0, Iterable.generate(list.length, (i) => rng.nextInt(256)));
        final newPassword = base64UrlEncode(list);
        await secureStorage.write(
          key: _passwordStorageKey,
          value: newPassword,
        );
      }
      // workaround for if we just wrote to the key and it still doesn't exist
      password = await secureStorage.read(key: _passwordStorageKey);
      if (password == null) throw MissingPluginException();
    } on MissingPluginException catch (e) {
      const FlutterSecureStorage()
          .delete(key: _passwordStorageKey)
          .catchError((_) {});
      Logs().w('Database encryption is not supported on this platform', e);
      _sendNoEncryptionWarning(e);
    } catch (e, s) {
      const FlutterSecureStorage()
          .delete(key: _passwordStorageKey)
          .catchError((_) {});
      Logs().w('Unable to init database encryption', e, s);
      _sendNoEncryptionWarning(e);
    }
  
    return password;
  }
  
  void _sendNoEncryptionWarning(Object exception) async {
    final store = await SharedPreferences.getInstance();
    final isStored = AppSettings.noEncryptionWarningShown.getItem(store);
  
    if (isStored == true) return;
  
    final l10n = await lookupL10n(PlatformDispatcher.instance.locale);
    ClientManager.sendInitNotification(
      l10n.noDatabaseEncryption,
      exception.toString(),
    );
  
    await AppSettings.noEncryptionWarningShown.setItem(store, true);
  }
  