From d067df8a51cf0b40720970756284cbf578914678 Mon Sep 17 00:00:00 2001
From: M <m@cakewallet.com>
Date: Fri, 3 Apr 2020 15:27:13 +0300
Subject: [PATCH] Added migration for android wallets and hives files.

---
 lib/src/domain/common/fs_migration.dart       | 70 +++++++++++++++++++
 .../domain/monero/monero_wallets_manager.dart | 18 ++---
 2 files changed, 80 insertions(+), 8 deletions(-)
 create mode 100644 lib/src/domain/common/fs_migration.dart

diff --git a/lib/src/domain/common/fs_migration.dart b/lib/src/domain/common/fs_migration.dart
new file mode 100644
index 000000000..537523aa4
--- /dev/null
+++ b/lib/src/domain/common/fs_migration.dart
@@ -0,0 +1,70 @@
+import 'dart:io';
+import 'package:path_provider/path_provider.dart';
+
+const reservedNames = ["flutter_assets", "wallets", "db"];
+
+Future<void> migrate_fs() async {
+  final appDocDir = await getApplicationDocumentsDirectory();
+
+  await migrate_hives(appDocDir: appDocDir);
+  await migrate_wallets(appDocDir: appDocDir);
+
+  appDocDir.listSync(recursive: true).forEach((item) => print(item.path));
+}
+
+Future<void> migrate_hives({Directory appDocDir}) async {
+  final dbDir = Directory('${appDocDir.path}/db');
+  final files = List<File>();
+
+  appDocDir.listSync().forEach((FileSystemEntity item) {
+    final ext = item.path.split('.').last;
+
+    if (item is File && (ext == "hive" || ext == "lock")) {
+      files.add(item);
+    }
+  });
+
+  if (!dbDir.existsSync()) {
+    dbDir.createSync();
+  }
+
+  files.forEach((File hive) {
+    final name = hive.path.split('/').last;
+    hive.copySync('${dbDir.path}/$name');
+    hive.deleteSync();
+  });
+}
+
+Future<void> migrate_wallets({Directory appDocDir}) async {
+  final walletsDir = Directory('${appDocDir.path}/wallets');
+  final moneroWalletsDir = Directory('${walletsDir.path}/monero');
+  final dirs = List<Directory>();
+
+  appDocDir.listSync().forEach((FileSystemEntity item) {
+    final name = item.path.split('/').last;
+
+    if (item is Directory && !reservedNames.contains(name)) {
+      dirs.add(item);
+    }
+  });
+
+  if (!moneroWalletsDir.existsSync()) {
+    await moneroWalletsDir.create(recursive: true);
+  }
+
+  dirs.forEach((Directory dir) {
+    final name = dir.path.split('/').last;
+    final newDir = Directory('${moneroWalletsDir.path}/$name');
+    newDir.createSync();
+
+    dir.listSync().forEach((file) {
+      if (file is File) {
+        final fileName = file.path.split('/').last;
+        file.copySync('${newDir.path}/$fileName');
+        file.deleteSync();
+      }
+    });
+
+    dir.deleteSync();
+  });
+}
diff --git a/lib/src/domain/monero/monero_wallets_manager.dart b/lib/src/domain/monero/monero_wallets_manager.dart
index 38abcf5d7..655f530b0 100644
--- a/lib/src/domain/monero/monero_wallets_manager.dart
+++ b/lib/src/domain/monero/monero_wallets_manager.dart
@@ -11,9 +11,10 @@ import 'package:cake_wallet/src/domain/common/wallet.dart';
 import 'package:cake_wallet/src/domain/monero/monero_wallet.dart';
 import 'package:cake_wallet/src/domain/common/wallet_description.dart';
 
-Future<String> pathForWallet({String name}) async {
+Future<String> pathForWallet(
+    {@required WalletType type, @required String name}) async {
   final directory = await getApplicationDocumentsDirectory();
-  final pathDir = directory.path + '/$name';
+  final pathDir = directory.path + '/wallets/${walletTypeToString(type).toLowerCase()}' + '/$name';
   final dir = Directory(pathDir);
 
   if (!await dir.exists()) {
@@ -34,9 +35,10 @@ class MoneroWalletsManager extends WalletsManager {
   Future<Wallet> create(String name, String password, String language) async {
     try {
       const isRecovery = false;
-      final path = await pathForWallet(name: name);
+      final path = await pathForWallet(type: WalletType.monero, name: name);
 
-      await monero_wallet_manager.createWallet(path: path, password: password, language: language);
+      await monero_wallet_manager.createWallet(
+          path: path, password: password, language: language);
 
       final wallet = await MoneroWallet.createdWallet(
           walletInfoSource: walletInfoSource,
@@ -56,7 +58,7 @@ class MoneroWalletsManager extends WalletsManager {
       String name, String password, String seed, int restoreHeight) async {
     try {
       const isRecovery = true;
-      final path = await pathForWallet(name: name);
+      final path = await pathForWallet(type: WalletType.monero, name: name);
 
       await monero_wallet_manager.restoreFromSeed(
           path: path,
@@ -89,7 +91,7 @@ class MoneroWalletsManager extends WalletsManager {
       String spendKey) async {
     try {
       const isRecovery = true;
-      final path = await pathForWallet(name: name);
+      final path = await pathForWallet(type: WalletType.monero, name: name);
 
       await monero_wallet_manager.restoreFromKeys(
           path: path,
@@ -117,7 +119,7 @@ class MoneroWalletsManager extends WalletsManager {
   @override
   Future<Wallet> openWallet(String name, String password) async {
     try {
-      final path = await pathForWallet(name: name);
+      final path = await pathForWallet(type: WalletType.monero, name: name);
       monero_wallet_manager.openWallet(path: path, password: password);
       final wallet = await MoneroWallet.load(walletInfoSource, name, type);
       await wallet.updateInfo();
@@ -132,7 +134,7 @@ class MoneroWalletsManager extends WalletsManager {
   @override
   Future<bool> isWalletExit(String name) async {
     try {
-      final path = await pathForWallet(name: name);
+      final path = await pathForWallet(type: WalletType.monero, name: name);
       return monero_wallet_manager.isWalletExist(path: path);
     } catch (e) {
       print('MoneroWalletsManager Error: $e');