/* Copyright 2014-2023 askanimus@gmail.com */

/* This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 *
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 *
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */
package askanimus.arbeitszeiterfassung2.datensicherung;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.backup.BackupManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.DocumentsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.Toast;

import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.view.ViewCompat;
import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import askanimus.arbeitszeiterfassung2.MainActivity;
import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.StorageHelper;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.ArbeitsplatzListe;
import askanimus.arbeitszeiterfassung2.datenbank.DatenbankHelper;
import askanimus.arbeitszeiterfassung2.datenbank.Datenbank_Migrate;
import askanimus.arbeitszeiterfassung2.datenbank.Datenbank_toMigrate;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;
import askanimus.arbeitszeiterfassung2.setup.LocaleHelper;
import askanimus.arbeitszeiterfassung2.setup.SettingsActivity;
import askanimus.arbeitszeiterfassung2.stempeluhr.StempeluhrStatus;

public class Datensicherung_Activity
        extends
        AppCompatActivity
        implements
        View.OnClickListener,
        PopupMenu.OnMenuItemClickListener,
        ISettings,
        Datensicherung_ViewAdapter.ItemClickListener {

    static public final String ACTIVITY_START = "start_datensicherung";
    public static final int INPUTSTREAM_LAENGE = 46;
    public static final int UPDATE_INTEVAL =5;

    RelativeLayout mRootView;
    private Context mContext;

    private ArrayList<String> listeSicherungen;
    private Datensicherung_ViewAdapter myAdapter;
    private RecyclerView listView;

    private Toolbar mToolbar;

    private int positionSicherung;

    private AppCompatEditText tPfad;

    private StorageHelper mStorageHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        setTheme(
                PreferenceManager
                        .getDefaultSharedPreferences(mContext)
                        .getBoolean(ASettings.KEY_THEMA_DUNKEL, false) ?
                        R.style.MyFullscreenTheme :
                        R.style.MyFullscreenTheme_Light
        );
        setContentView(R.layout.activity_datensicherung);
        mRootView = findViewById(R.id.D_root);
        mToolbar = findViewById(R.id.D_toolbar);
        if(getSupportActionBar() == null)
            setSupportActionBar(mToolbar);

        getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                BackPressed();
            }
        });
    }

	@Override
	protected void attachBaseContext(Context base) {
		super.attachBaseContext(LocaleHelper.onAttach(base));
	}


    @Override
    protected void onResume() {
        super.onResume();

        ASettings.init(mContext, this::resume);
    }

    private void resume() {
        mToolbar.setTitle(ASettings.res.getString(R.string.title_activity_datensicherung));
        listView = findViewById(R.id.D_liste_sicherungen);
        tPfad = findViewById(R.id.D_wert_verzeichnis);
        tPfad.setOnClickListener(this);

        // das Backup Verzeichnis abgleichen
        if (mStorageHelper == null) {
            String mExportPfad;
            mExportPfad = Environment.getExternalStorageDirectory().getAbsolutePath()
                    + File.separator
                    + getString(R.string.app_verzeichnis)
                    + File.separator
                    + getString(R.string.app_verzeichnis_backup
            );
            mExportPfad = ASettings.mPreferenzen.getString(
                    ISettings.KEY_BACKUP_DIR,
                    mExportPfad
            );

            if (mExportPfad != null) {
                mStorageHelper = new StorageHelper(
                        this,
                        mExportPfad,
                        DatenbankHelper.DB_F_BACKUP_DIR,
                        ISettings.KEY_BACKUP_DIR,
                        true,
                        REQ_FOLDER_PICKER_WRITE_BACKUP
                );
            }
        }

        if (mStorageHelper.isWritheable()) {
            updateUI();
        }
    }

    void updateUI(){
        AppCompatButton bAktSicherung = findViewById(R.id.D_button_sicherung);
        ViewCompat.setBackgroundTintList(bAktSicherung, ASettings.aktJob.getFarbe_Button());
        bAktSicherung.setTextColor(ASettings.aktJob.getFarbe_Schrift_Button());

        if (mStorageHelper.isWritheable()) {
            tPfad.setText(mStorageHelper.getPfadSubtree());
            // Die Liste der Datensicherungen erzeugen, wenn sie nicht schon angelegt wurde
            if(listeSicherungen == null){
                setUpListe();
            }
            // der Button zum Backup anlegen
            bAktSicherung.setOnClickListener(this);
        } else {
            bAktSicherung.setEnabled(false);
        }
    }

    /*
     * Rückmeldung vom Rechtemanagent nach Rechteeinforderung
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
            requestCode = requestCode & 0x0000ffff;

            if (requestCode == REQ_DEMAND_WRITE) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // Recht verweigert die Exportaktivity wird geschlossen
                    Toast.makeText(
                            Datensicherung_Activity.this,
                            getString(R.string.err_keine_berechtigung),
                            Toast.LENGTH_LONG
                    ).show();
                    finish();
                }
            }
        }
    }


    /*
     * Liste der Sicherungen neu anlegen
     * wird beim Start der Activity und nach jeder Änderung( Eintrag löschen) ausgeführt
     */
    private void setUpListe() {
        myAdapter = new Datensicherung_ViewAdapter();
        listeSicherungen = myAdapter.setUp(mContext, mStorageHelper, this, true);
        GridLayoutManager gLayoutManager = new GridLayoutManager(
                mContext,
                1);
        listView.setLayoutManager(gLayoutManager);
        listView.setAdapter(myAdapter);
    }

    private void BackPressed() {
        // alten Zustand der App wieder anzeigen
        SharedPreferences.Editor mEdit = ASettings.mPreferenzen.edit();
        mEdit.putBoolean(ISettings.KEY_RESUME_VIEW, true).apply();

        Intent mMainIntent = new Intent();
        mMainIntent.setClass(mContext, MainActivity.class);
        mMainIntent.setAction(ISettings.APP_RESET);
        mMainIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
        startActivity(mMainIntent);

        finish();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Ein Einstellungen Icon in der Toolbar anzeigen
        getMenuInflater().inflate(R.menu.menu_sicherungen_einstellungen, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.sicherung_action_setting){
            Intent iSettings = new Intent();
            iSettings.setClass(this, SettingsActivity.class);
            iSettings.putExtra(KEY_EDIT_JOB, ASettings.aktJob.getId());
            iSettings.putExtra(ARG_NUR_BACKUP, true);
            iSettings.putExtra(KEY_INIT_SEITE, SETUP_SEITE_DATENSICHERUNG);
            finish();
            startActivity(iSettings);
        }
        return super.onOptionsItemSelected(item);
    }

    // Popup Menu mit Optionen zur Wiederherstellung
    public void showMenu(View view) {
        PopupMenu popup;
        popup = new PopupMenu(this, view);
        popup.setOnMenuItemClickListener(this);
        if (view.getId() == R.id.ID_button_send) {
            popup.inflate(R.menu.menu_sicherung_send);
        } else {
            popup.inflate(R.menu.menu_sicherung);
        }
        popup.show();
    }


    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        int id = menuItem.getItemId();
        final String mDateiname = listeSicherungen.get(positionSicherung);
            PackageManager pm = mContext.getPackageManager();

            if (id == R.id.sich_action_restore) {
                restoreSicherung(mDateiname);
            } else if (id == R.id.sich_action_kopie) {
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
                intent.putExtra("android.content.extra.FANCY", true);
                intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    DocumentFile f = mStorageHelper.getVerzeichnisFile();
                    if (f != null) {
                        intent.putExtra(
                                DocumentsContract.EXTRA_INITIAL_URI,
                                f.getUri()
                        );
                    }
                }

                intent.putExtra(DatenbankHelper.DB_F_NAME, mDateiname);
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
                startActivityForResult(intent, REQ_MAKE_COPY);
            } else if (id == R.id.sich_action_send) {
                String s = getString(R.string.sich_von) + " " +
                        ASettings.mPreferenzen.getString(ISettings.KEY_USERNAME, "");

                //Datei als ausgewählter Typ mailen
                Intent emailIntent = new Intent(Intent.ACTION_SEND);
                emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{""});
                emailIntent.putExtra(Intent.EXTRA_SUBJECT, s);
                emailIntent.putExtra(Intent.EXTRA_TEXT,
                        getString(R.string.sich_mail)
                        + " "
                        + ASettings.mPreferenzen.getString(ISettings.KEY_USERNAME, "")
                        + "."
                );
                //emailIntent.setType("message/rfc822");
                emailIntent.setType(Datenbank_Backup.DATEI_TYP_DB);
                Uri mURI = mStorageHelper.getDateiUri(mDateiname);
                if(mURI != null) {
                    emailIntent.putExtra(Intent.EXTRA_STREAM, mURI);

                    if (emailIntent.resolveActivity(pm) != null) {
                        startActivity(
                                Intent.createChooser(emailIntent, getString(R.string.mailwahl))
                        );
                    } else {
                        Toast.makeText(mContext, R.string.no_app, Toast.LENGTH_SHORT).show();
                    }
                }
            } else if (id == R.id.sich_action_share) {
                Intent shareIntent = new Intent();
                shareIntent.setAction(Intent.ACTION_SEND);
                shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                shareIntent.setType(Datenbank_Backup.DATEI_TYP_DB);

                Uri mUri = mStorageHelper.getDateiUri(mDateiname);
                if(mUri != null) {
                    shareIntent.putExtra(Intent.EXTRA_STREAM, mUri);

                    if (shareIntent.resolveActivity(pm) != null) {
                        startActivity(
                                Intent.createChooser(shareIntent, getString(R.string.zielwahl))
                        );
                    } else {
                        Toast.makeText(mContext, R.string.no_app, Toast.LENGTH_SHORT).show();
                    }
                }

            } else if (id == R.id.sich_action_delete) {
                deleteSicherung(mDateiname);
            }
      //  }
        return false;
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.D_button_sicherung) {
            backupTask();
            requestBackup();
        } else if (id == R.id.D_wert_verzeichnis) {
            // einen neuen Speicherpfad wählen
            mStorageHelper.waehlePfad();
        }
    }

    @Override
    public void onSicherungClick(int position, int action, View view) {
        positionSicherung = position;
        switch (action){
            case Datensicherung_ViewAdapter.ACTION_DELETE:
                deleteSicherung(listeSicherungen.get(position));
                break;
            case Datensicherung_ViewAdapter.ACTION_RESTORE:
                restoreSicherung(listeSicherungen.get(position));
                break;
            default:
                showMenu(view);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        requestCode = requestCode & 0x0000ffff;

        if (resultCode == RESULT_OK) {
            Uri treeUri = data.getData();
            if (treeUri != null) {
                getContentResolver()
                        .takePersistableUriPermission(
                                treeUri,
                                Intent.FLAG_GRANT_READ_URI_PERMISSION
                                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                        );

                switch (requestCode) {
                    case REQ_FOLDER_PICKER_WRITE_BACKUP:
                        if (mStorageHelper != null) {
                            mStorageHelper.setPfad(data.getDataString());
                            if (mStorageHelper.isExists()) {
                                tPfad.setText(mStorageHelper.getPfadSubtree());
                                setUpListe();
                            }
                        }
                        break;
                    case REQ_MAKE_COPY:
                        DocumentFile mQuelle = mStorageHelper
                                .getVerzeichnisFile()
                                .findFile(listeSicherungen.get(positionSicherung));
                        DocumentFile pickedDir = DocumentFile.fromTreeUri(mContext, treeUri);
                        kopieTask(mQuelle, pickedDir);
                        break;
                }
            }
        }
    }

    // Backup im Google Konto anfordern
    public void requestBackup() {
        BackupManager bm = new BackupManager(this);
        try {
            bm.dataChanged();
        } catch (NullPointerException ne){
            ne.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        if(isChangingConfigurations()) {
            Intent mSicherungIntent = new Intent();
            mSicherungIntent.setClass(this, Datensicherung_Activity.class);
            mSicherungIntent.putExtra(ISettings.KEY_EDIT_JOB, ASettings.aktJob.getId());
            mSicherungIntent.setAction(ISettings.APP_RESET);
            mSicherungIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(mSicherungIntent);
        }
        super.onDestroy();
    }

    // stellt die Daten aus der ausgewählten Datei wieder her
    void restoreSicherung(final String name) {
        AlertDialog.Builder restorDialog = new AlertDialog.Builder(this);
        restorDialog.setMessage(getString(R.string.sich_frage_restore, name))
                .setIcon(R.mipmap.ic_launcher_foreground)
                .setTitle(R.string.sich_restore)
                .setPositiveButton(R.string.ja, (dialog, id) -> {
                    // alle Stempeluhren stoppen/löschen
                    for (Arbeitsplatz job : ASettings.jobListe.getListe()) {
                        StempeluhrStatus stempeluhr = new StempeluhrStatus(job, 0);
                        if(stempeluhr.getStatus() != StempeluhrStatus.WIDGET_STATUS_NEU){
                            stempeluhr.delete(ASettings.mPreferenzen);
                        }
                    }

                    // Daten wiederherstellen
                    if(name.endsWith(".xml")){
                        restoreTask(name, false);
                    } else if (name.endsWith(".db")){
                        restoreTask(name, true);
                    } else {
                        importTask(name);
                    }

                })
                .setNegativeButton(R.string.nein, (dialog, id) -> {
                    // nichts tun
                });
        // den Dialog erzeugen und anzeigen
        restorDialog.create().show();
    }

    // Löscht die ausgewählte Sicherungsdatei
    void deleteSicherung(final String name) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(getString(R.string.sich_frage_delete, name))
                .setIcon(R.mipmap.ic_launcher_foreground)
                .setTitle(R.string.delete)
                .setPositiveButton(R.string.ja, (dialog, id) -> {
                    if(mStorageHelper.isExists()) {
                        DocumentFile deleteFile = mStorageHelper.getVerzeichnisFile().findFile(name);// makeDocumentFile(mStorageHelper.getPfad(), name);
                        ////////////////////////////////////////////////////////////////////////////////////////////
                        // Löschen
                        ////////////////////////////////////////////////////////////////////////////////////////////
                        if (deleteFile != null && deleteFile.exists()) {
                            deleteTask(deleteFile);
                        }
                    }
                })
                .setNegativeButton(R.string.nein, (dialog, id) -> {
                    // nichts tun
                });
        // den Dialog erzeugen und anzeigen
        builder.create().show();
    }

    /*
    * Innere Klasse zum löschen einer Sicherung ausgelagert als Arbeitstask
     */
    private void deleteTask(DocumentFile datei) {
        Handler mHandler = new Handler();

        new Thread(() -> {
            boolean mStatus = false;
            if (datei != null && datei.exists()) {
                if (datei.delete())
                    mStatus = true;
            }
            final boolean fStatus = mStatus;
            mHandler.post(() -> {
                listeSicherungen.remove(positionSicherung);
                // Toast ausgeben
                Toast toast = Toast.makeText(
                        mContext,
                        fStatus ?
                                getString(R.string.delete_toast_erfolg) :
                                getString(R.string.delete_toast_miserfolg),
                        Toast.LENGTH_LONG);
                toast.show();

                // Liste der Sicherungen neu einlesen
                myAdapter.notifyItemRemoved(positionSicherung);
            });
        }).start();
    }

    /*
     * Innere Klasse zum kopieren einer Sicherung ausgelagert als Arbeitstask
     */
    private void kopieTask(DocumentFile quelle, DocumentFile zielpfad) {
        Handler mHandler = new Handler();

        new Thread(() -> {
            boolean mStatus = false;
            InputStream sourceStream = null;
            OutputStream destStream = null;
            try {
                DocumentFile mZiel = zielpfad.createFile("text/xml", quelle.getName());
                sourceStream = getContentResolver().openInputStream(quelle.getUri());
                destStream = getContentResolver().openOutputStream(mZiel.getUri());
                byte[] buffer = new byte[1024];
                int read;
                while ((read = sourceStream.read(buffer)) != -1) {
                    destStream.write(buffer, 0, read);
                }
                sourceStream.close();
                // die kopierten Daten schreiben
                assert destStream != null;
                destStream.flush();
                destStream.close();
                mStatus = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (sourceStream != null)
                        sourceStream.close();
                    if (destStream != null)
                        destStream.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }


            // Erfolgmeldung
            final boolean fStatus = mStatus;
            mHandler.post(() -> {
                // Toast ausgeben
                Toast toast = Toast.makeText(
                        mContext,
                        fStatus ?
                                getString(R.string.copy_ok, getString(R.string.datei)) :
                                getString(R.string.copy_fail, getString(R.string.datei), ""),
                        Toast.LENGTH_LONG);
                toast.show();
            });
        }).start();
    }


    /*
     * Sicherung, ausgelagert als Arbeits Task
     */
    protected void backupTask() {
        AtomicReference<String> filename = new AtomicReference<>("");
        final ProgressDialog mDialog = new ProgressDialog(mContext);
        Context mContext = this;

        // Fortschritsdialog öffnen
        mDialog.setIndeterminate(true);
        mDialog.setIndeterminateDrawable(
                ResourcesCompat.getDrawable(
                        getResources(),
                        R.drawable.progress_dialog_anim,
                        getTheme()));
        mDialog.setMessage(getString(R.string.progress_sicherung));
        mDialog.setCancelable(false);
        mDialog.show();

        Handler mHandler = new Handler();
        new Thread(() -> {
            //boolean mStatus = false;
            int mStatus = AAutoBackup.STATUS_OK;
            // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();

            // zuerst die allgem. Einstellungen sichern
            ContentValues mWerte = new ContentValues();
            mWerte.put(
                    DatenbankHelper.DB_F_VERSION,
                    ASettings.mPreferenzen.getLong(ISettings.KEY_VERSION_APP, 0)
                    );
            mWerte.put(DatenbankHelper.DB_F_JOB, ASettings.aktJob.getId());
            mWerte.put(DatenbankHelper.DB_F_VIEW, ASettings.mPreferenzen.getInt(ISettings.KEY_ANZEIGE_VIEW, ISettings.VIEW_TAG));

            // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
            ASettings.mDatenbank.update(DatenbankHelper.DB_T_SETTINGS, mWerte,
                    DatenbankHelper.DB_F_ID + "=?", new String[]{String.valueOf(1)});

            // ASettings.mDatenbank.close();

            Datenbank_Backup mBackup = new Datenbank_Backup(mContext, mStorageHelper);
            //try {
            try {
                filename.set(mBackup.backup());
            } catch (IOException ioe){
                ioe.printStackTrace();
                mStatus = AAutoBackup.STATUS_FAIL;
            }
                //mStatus = true;
            /*} catch (NullPointerException | ParserConfigurationException | IOException |
                     TransformerException e) {
                e.printStackTrace();
                if (!mStorageHelper.isExists()) {
                    mStatus = STATUS_NO_DIRECTORY;
                } else if (!mStorageHelper.isWritheable()) {
                    mStatus = STATUS_NO_ACCESS;
                } else {
                    mStatus = STATUS_FAIL;
                }
            } catch (OutOfMemoryError me) {
                mStatus = STATUS_NO_MEMORY;
            }*/

            final int fStatus = mStatus;

            mHandler.post(() -> {
                // Fortschrittsdialog schliessen
                if (mDialog.isShowing()) {
                    mDialog.dismiss();
                }
                String meldung;

                switch (fStatus) {
                    case AAutoBackup.STATUS_OK:
                        meldung = getString(R.string.not_text_autobackup);
                        break;
                    case AAutoBackup.STATUS_NO_DIRECTORY:
                        meldung = getString(
                                R.string.not_text_autobackup_fail,
                                getString(R.string.not_no_exists,
                                        mStorageHelper.getPfadSubtree())
                        );
                        break;
                    case AAutoBackup.STATUS_NO_ACCESS:
                        meldung = getString(
                                R.string.not_text_autobackup_fail,
                                getString(R.string.not_no_writeable,
                                        mStorageHelper.getPfadSubtree())
                        );
                        break;
                    case AAutoBackup.STATUS_NO_MEMORY:
                        meldung = getString(
                                R.string.not_text_autobackup_fail,
                                getString(R.string.not_no_memory)
                        );
                        break;
                    default:
                        meldung = getString(R.string.not_titel_autobackup_fail);
                }
                // Toast ausgeben
                Toast toast = Toast.makeText(
                        mContext,
                        meldung,
                        Toast.LENGTH_LONG);
                toast.show();

                // Liste der Sicherungen aktuallisieren
                if (!filename.toString().isEmpty()) {
                    listeSicherungen.add(0, filename.toString());
                    myAdapter.notifyItemInserted(0);
                }
            });
        }).start();
    }

    /*
     * Wiederherstellung der Sicherungen im Hintergrund
     */
    private void restoreTask(String pfad, boolean isDB) {
        final ProgressDialog mDialog = new ProgressDialog(mContext);

        // Fortschritsdialog öffnen
        mDialog.setIndeterminate(true);
        mDialog.setIndeterminateDrawable(
                ResourcesCompat.getDrawable(
                        getResources(),
                        R.drawable.progress_dialog_anim,
                        getTheme()));
        mDialog.setMessage(getString(R.string.progress_restore));
        mDialog.setCancelable(false);
        mDialog.show();

        Handler mHandler = new Handler();
        new Thread(() -> {
            boolean mStatus = false;
            long aktJob = 0;

            //SQLiteDatabase mDatenbank = ASettings.openDatenbank();
            Datenbank_Backup mBackup = new Datenbank_Backup(mContext, mStorageHelper);
            try {
                if (isDB){
                    aktJob = mBackup.restore(pfad);
                } else {
                    aktJob = mBackup.restoreXML(pfad);
                }
                mStatus = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Erfolgsmeldung ausgeben
            final boolean fStatus = mStatus;
            final long newAktJob = aktJob;
            mHandler.post(() -> {
                // Fortschrittsdialog schliessen
                if(mDialog.isShowing()) {
                    mDialog.dismiss();
                }
                reset(fStatus, newAktJob);
            });
        }).start();
    }

    /*
     * Import Task - importiert Sicherungen aus "Arbeitszeiterfassung"
     */
    private void importTask(String filename) {
        final ProgressDialog mDialog = new ProgressDialog(mContext);

        // Fortschritsdialog öffnen
        mDialog.setIndeterminate(true);
        mDialog.setIndeterminateDrawable(
                ResourcesCompat.getDrawable(
                        getResources(),
                        R.drawable.progress_dialog_anim,
                        Objects.requireNonNull(mContext).getTheme()));
        mDialog.setMessage(getString(R.string.mig_prog_import));
        mDialog.setCancelable(false);
        mDialog.show();

        Handler mHandler = new Handler();
        new Thread(() -> {
            long aktJob = 0;
            //String p = mStorageHelper.getPfad();
            boolean mStatus = false;
            // if (p != null) {
            SQLiteOpenHelper importDB = new Datenbank_toMigrate(mContext);
            Datenbank_Migrate mMigradeDB = new Datenbank_Migrate(importDB, mStorageHelper, mContext);
            try {
                // Datenbank neu anlegen
                ASettings.resetDatenbank(mContext);
                // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();

                // Einstellungen einlesen und Migration beginnen
                mMigradeDB.einlesen(filename);
                mHandler.post(() -> mDialog.setMessage(ASettings.res.getString(R.string.mig_prog_einstellungen)));
                aktJob = mMigradeDB.Migrate_Einstellungen(ASettings.mDatenbank);
                mHandler.post(() -> mDialog.setMessage(ASettings.res.getString(R.string.mig_prog_arbeitsplatz)));
                aktJob = mMigradeDB.Migrate_Arbeitsplatz(ASettings.mDatenbank, aktJob);
                mHandler.post(() -> mDialog.setMessage(ASettings.res.getString(R.string.mig_prog_eort)));
                mMigradeDB.Migrate_Eorte();
                mHandler.post(() -> mDialog.setMessage(ASettings.res.getString(R.string.mig_prog_zeit)));
                mMigradeDB.Migrate_Zeiten(ASettings.mDatenbank);
                mMigradeDB.Delete_AlteDB();
                // ASettings.mDatenbank.close();

                mStatus = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            // }


            final boolean fStatus = mStatus;
            final long newAktJob = aktJob;
            mHandler.post(() -> {
                // Fortschrittsdialog schliessen
                if(mDialog.isShowing()) {
                    mDialog.dismiss();
                }
                reset(fStatus, newAktJob);
            });
        }).start();
    }

    @SuppressLint("Range")
    private void reset(boolean status, long aktJob){
        if(ASettings.stundenDBHelper != null) {
            ASettings.stundenDBHelper.close();
        }
        ASettings.stundenDBHelper = new DatenbankHelper(mContext);
        ASettings.mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
        ASettings.aktJob = new Arbeitsplatz(aktJob);
        ASettings.jobListe = new ArbeitsplatzListe(ASettings.aktJob);
        // Allgemeine Einstellungen wiederherstellen
        String mSQL;
        Cursor mResult;

        mSQL = "SELECT * FROM " + DatenbankHelper.DB_T_SETTINGS +
                " WHERE " + DatenbankHelper.DB_F_ID + "=1 LIMIT 1 ";

        mResult = ASettings.mDatenbank.rawQuery(mSQL, null);

        if (mResult.getCount() > 0) {
            SharedPreferences.Editor mEdit = ASettings.mPreferenzen.edit();
            int mOptionen;
            mResult.moveToFirst();

            mEdit.putLong(ISettings.KEY_JOBID, mResult.getLong(mResult.getColumnIndex(DatenbankHelper.DB_F_JOB)));
            mEdit.putString(ISettings.KEY_USERNAME, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_USER)));
            mEdit.putString(ISettings.KEY_USERANSCHRIFT, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_ANSCHRIFT)));
            mEdit.putString(ISettings.KEY_ANZEIGE_W_KUERZEL, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_W_KUERZEL)));
            //mEdit.putString(ISetup.KEY_ANZEIGE_W_TRENNER, mResult.getString(mResult.getColumnIndex(Datenbank.DB_F_W_TRENNER)));
            mEdit.putString(ISettings.KEY_ANZEIGE_E_KUERZEL, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_E_KUERZEL)));
            mEdit.putInt(ISettings.KEY_ANZEIGE_VIEW, mResult.getInt(mResult.getColumnIndex(DatenbankHelper.DB_F_VIEW)));
            mEdit.putString(ISettings.KEY_DATEN_DIR, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_DATEN_DIR)));
            if (mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_BACKUP_DIR)) == null)
                mEdit.putString(ISettings.KEY_BACKUP_DIR, mResult.getString(mResult.getColumnIndex(DatenbankHelper.DB_F_BACKUP_DIR)));

            mOptionen = mResult.getInt(mResult.getColumnIndex(DatenbankHelper.DB_F_OPTIONEN));

            // die Option "dezimale Minutenanzeige" ist seit V 1.02.94 in die Arbeitsplatzeinstellungen gewandert
            if (mResult.getInt(mResult.getColumnIndex(DatenbankHelper.DB_F_VERSION)) < 10294) {
                boolean dezimal = ((mOptionen & ISettings.OPT_ANZ_DEZIMAL) != 0);
                //ArbeitsplatzListe aListe = new ArbeitsplatzListe(null);
                ArbeitsplatzListe aListe = ASettings.jobListe;
                for (Arbeitsplatz a : aListe.getListe()) {
                    a.setOption(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL, dezimal);
                    a.schreibeJob();
                }
            }
            // mEdit.putBoolean(Einstellungen.KEY_ANZEIGE_DEZIMAL, ((mOptionen & Einstellungen.OPT_ANZ_DEZIMAL) != 0));
            mEdit.putBoolean(ISettings.KEY_ANZEIGE_ERW_SALDO, ((mOptionen & ISettings.OPT_ANZ_ERW_SALDO) != 0));
            mEdit.putBoolean(ISettings.KEY_ANZEIGE_UMG_SORT, ((mOptionen & ISettings.OPT_ANZ_UMG_SORT) != 0));
            mEdit.putBoolean(ISettings.KEY_THEMA_DUNKEL, ((mOptionen & ISettings.OPT_ANZ_THEMA_DUNKEL) != 0));

            mEdit.apply();

            if (!mResult.isNull(mResult.getColumnIndex(DatenbankHelper.DB_F_SPRACHE))) {
                String s = LocaleHelper.getLanguage(mContext);

                switch (s) {
                    case "it":
                        LocaleHelper.setLocale(mContext, "it", Locale.getDefault().getCountry());
                        break;
                    case "de":
                        LocaleHelper.setLocale(mContext, "de", Locale.getDefault().getCountry());
                        break;
                    default:
                        LocaleHelper.setLocale(mContext, "en", Locale.getDefault().getCountry());
                }
            }

        }
        mResult.close();
        // ASettings.mDatenbank.close();
        // den zuletzt aktiven arbeitsplatz aus der datenbank lesen
        //ASettings.aktJob = new Arbeitsplatz(ASettings.mPreferenzen.getLong(ISetup.KEY_JOBID, 0));

        // Toast ausgeben
        Toast toast = Toast.makeText(
                mContext,
                status ?
                        getString(R.string.restore_toast_erfolg) :
                        getString(R.string.restore_toast_misserfolg),
                Toast.LENGTH_LONG);
        toast.show();
        ASettings.zustand = ISettings.INIT_ZUSTAND_UNGELADEN;
        // alten Zustand der App wieder anzeigen
        SharedPreferences.Editor mEdit = ASettings.mPreferenzen.edit();
        mEdit.putBoolean(ISettings.KEY_RESUME_VIEW, true).apply();

        Intent mMainIntent = new Intent();
        mMainIntent.setClass(this, MainActivity.class);
        mMainIntent.setAction(ISettings.APP_RESET);
        mMainIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //mMainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //finish();
        startActivity(mMainIntent);
    }
}
