/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package info.zamojski.soft.towercollector.dev;

import info.zamojski.soft.towercollector.R;
import info.zamojski.soft.towercollector.utils.FileUtils;
import info.zamojski.soft.towercollector.utils.StorageUtils;
import timber.log.Timber;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
import java.util.Map.Entry;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.widget.Toast;

import com.example.android.internal.util.XmlUtils;

public class PreferencesOperations {

    public static void importPreferences(Context context) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        File srcFile = getPreferencesExportPath();
        boolean loaded = loadSharedPreferencesFromFile(context, prefs, srcFile);
        if (loaded) {
            Toast.makeText(context, R.string.preferences_import_message, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(context, R.string.preferences_import_export_failed_message, Toast.LENGTH_LONG).show();
        }
    }

    public static void exportPreferences(Context context) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        File dstFile = getPreferencesExportPath();
        boolean saved = saveSharedPreferencesToFile(context, prefs, dstFile);
        if (saved) {
            Toast.makeText(context, R.string.preferences_export_message, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(context, R.string.preferences_import_export_failed_message, Toast.LENGTH_LONG).show();
        }
    }

    public static void clearPreferences(Context context) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        Editor prefEdit = prefs.edit();
        prefEdit.clear();
        boolean cleared = prefEdit.commit();
        if (cleared) {
            Timber.d("clearPreferences(): Preferences cleared");
            Toast.makeText(context, "Preferences cleared", Toast.LENGTH_LONG).show();
        } else {
            Timber.e("clearPreferences(): Failed to clear preferences");
        }
    }

    private static boolean saveSharedPreferencesToFile(Context context, SharedPreferences prefs, File dst) {
        boolean res = false;
        ObjectOutputStream output = null;
        try {
            if (StorageUtils.isExternalMemoryWritable()) {
                File externalStorage = Environment.getExternalStorageDirectory();
                if (externalStorage.canWrite()) {
                    FileUtils.checkAccess(dst);
                    output = new ObjectOutputStream(new FileOutputStream(dst));
                    XmlUtils.writeMapXml(prefs.getAll(), output);
                    res = true;
                    Timber.d("saveSharedPreferencesToFile(): Preferences exported");
                }
                Timber.d("saveSharedPreferencesToFile(): External storage is read only");
                Toast.makeText(context, R.string.export_toast_storage_read_only, Toast.LENGTH_LONG).show();
            }
            Timber.d("saveSharedPreferencesToFile(): External storage is not available");
            Toast.makeText(context, R.string.export_toast_no_storage, Toast.LENGTH_LONG).show();
        } catch (Exception ex) {
            Timber.e(ex, "saveSharedPreferencesToFile(): Cannot export preferences");
        } finally {
            try {
                if (output != null) {
                    output.flush();
                    output.close();
                }
            } catch (IOException ex) {
                Timber.e(ex, "saveSharedPreferencesToFile(): Failed to close file stream");
            }
        }
        return res;
    }

    private static boolean loadSharedPreferencesFromFile(Context context, SharedPreferences prefs, File src) {
        boolean res = false;
        ObjectInputStream input = null;
        try {
            if (StorageUtils.isExternalMemoryWritable() || StorageUtils.isExternalMemoryPresent()) {
                File externalStorage = Environment.getExternalStorageDirectory();
                if (externalStorage.canRead()) {
                    input = new ObjectInputStream(new FileInputStream(src));
                    Editor prefEdit = prefs.edit();
                    prefEdit.clear();
                    @SuppressWarnings("unchecked")
                    Map<String, ?> entries = XmlUtils.readMapXml(input);
                    for (Entry<String, ?> entry : entries.entrySet()) {
                        Object v = entry.getValue();
                        String key = entry.getKey();

                        if (v instanceof Boolean)
                            prefEdit.putBoolean(key, (Boolean) v);
                        else if (v instanceof Float)
                            prefEdit.putFloat(key, (Float) v);
                        else if (v instanceof Integer)
                            prefEdit.putInt(key, (Integer) v);
                        else if (v instanceof Long)
                            prefEdit.putLong(key, (Long) v);
                        else if (v instanceof String)
                            prefEdit.putString(key, ((String) v));
                    }
                    prefEdit.apply();
                    Timber.d("loadSharedPreferencesFromFile(): Preferences imported");
                    res = true;
                }
                Timber.d("saveSharedPreferencesToFile(): External storage is read only");
                Toast.makeText(context, R.string.export_toast_storage_read_only, Toast.LENGTH_LONG).show();
            }
            Timber.d("saveSharedPreferencesToFile(): External storage is not available");
            Toast.makeText(context, R.string.export_toast_no_storage, Toast.LENGTH_LONG).show();
        } catch (Exception ex) {
            Timber.e(ex, "loadSharedPreferencesFromFile(): Cannot import preferences");
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
            } catch (IOException ex) {
                Timber.e(ex, "loadSharedPreferencesFromFile(): Failed to close file stream");
            }
        }
        return res;
    }

    private static File getPreferencesExportPath() {
        return new File(FileUtils.getExternalStorageAppDir(), "preferences.xml");
    }
}

@@ -3336,33 +3336,44 @@
                %7D
-%0A
+ else %7B%0A    
                 
@@ -3438,32 +3438,36 @@
 is read only%22);%0A
+    
                 
@@ -3562,34 +3562,63 @@
 ();%0A            
+ 
+   
 %7D%0A
+            %7D else %7B%0A    
             Timb
@@ -3695,32 +3695,36 @@
 %22);%0A            
+   
+ 
 Toast.makeText(c
@@ -3784,32 +3784,46 @@
 H_LONG).show();%0A
+            %7D%0A
         %7D catch 
@@ -5942,33 +5942,44 @@
                %7D
-%0A
+ else %7B%0A    
                 
@@ -6035,33 +6035,36 @@
  storage is 
-read only
+not readable
 %22);%0A        
@@ -6063,32 +6063,36 @@
                 
+    
 Toast.makeText(c
@@ -6121,33 +6121,26 @@
 t_toast_
+no_
 storage
-_read_only
 , Toast.
@@ -6152,32 +6152,36 @@
 H_LONG).show();%0A
+    
             %7D%0A  
@@ -6170,32 +6170,57 @@
               %7D%0A
+            %7D else %7B%0A    
             Timb
@@ -6285,32 +6285,36 @@
 ot available%22);%0A
+    
             Toas
@@ -6386,32 +6386,46 @@
 H_LONG).show();%0A
+            %7D%0A
         %7D catch 

Fix toast messages displayed incorrectly when importing and exporting preferences.