/* 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.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;

import java.util.Calendar;
import java.util.Date;

import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;

public abstract class AAutoBackup implements ISettings {
    static final int STATUS_OK = 0;
    static final int STATUS_NO_DIRECTORY = 1;
    static final int STATUS_NO_ACCESS = 2;
    static final int STATUS_NO_MEMORY = 3;
    static final int STATUS_FAIL = 4;
    static final int REQESTCODE = 777;
    static final String AUTOBACKUP = "make_backup";
    static final String CHANNEL_ID = "999";
    static final long DEFAULT_BACKUP_OFFSET = 604800000;  // 7*24*60*60*1000 = 1 Backup pro Woche
    public static void init(Context context, int backupIntervall, int backupSchritte) {
        SharedPreferences.Editor mEditor = ASettings.mPreferenzen.edit();

        // alten Timer löschen
        deleteTimer(context);

        if(backupIntervall > AUTOBACKUP_NO) {
            // die Millisekunden zwischen zwei Backups setzen
            Calendar cal = Calendar.getInstance();
            cal.setTimeInMillis(0);
            cal.add(AUTOBACKUP_INTERVAL[backupIntervall], backupSchritte);
            mEditor.putLong(KEY_AUTOBACKUP_OFFSET, cal.getTimeInMillis()).apply();
            // neuen Timer setzen
            setTimer(context);
        } else {
            mEditor.putLong(KEY_AUTOBACKUP_LETZTES, 0).apply();
            mEditor.putLong(KEY_AUTOBACKUP_OFFSET, 0).apply();
        }
    }

    public static void updateTimer(Context context){
        ASettings.init(context, ()->setTimer(context));
    }

    private static void setTimer(Context context) {
        int backupIntervall = ASettings.mPreferenzen.getInt(KEY_AUTOBACKUP_INTERVAL, AUTOBACKUP_NO);

        if (backupIntervall > AUTOBACKUP_NO) {
            // die Millisekunden zwischen zwei Backups
            long millisOffset = ASettings.mPreferenzen.getLong(KEY_AUTOBACKUP_OFFSET, DEFAULT_BACKUP_OFFSET);

            // das letzte Backup was angelegt wurde
            long millisLastBackup = ASettings.mPreferenzen.getLong(KEY_AUTOBACKUP_LETZTES, 0);

            // die aktuelle Zeit ermitteln und 2 Minuten aufschlagen damit der neue Timer
            // sicher ausgeführt wird
            long millisAktTime = new Date().getTime() + 120000;

            // den Zeitpunkt des nächsten Backups berechnen
            long millisNextBackup;

            // das Backupdatum auf das Datum des letzten Backups oder von heute setzen
            if(millisLastBackup == 0) {
               millisNextBackup = millisAktTime;
            } else {
                millisNextBackup = millisLastBackup;
                // so lange das Backupintervall addieren, bis das Datum nach dem aktuellen Datum liegt
                do {
                    millisNextBackup += millisOffset;
                } while (millisNextBackup < millisAktTime);
            }
            // den Alarmmanger als wiederholten Alarm setzen
            // der Empfänger der Alarmierung
            Intent intent = new Intent(context, AutoBackup_Receiver.class);
            intent.setAction(AUTOBACKUP);

            AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            mAlarmManager.setInexactRepeating(
                    AlarmManager.RTC_WAKEUP, // wird auch ausgeführt wenn das Handy im Ruhezustand
                    millisNextBackup, // der Zeitpunkt des nächsten Aufrufs
                    millisOffset, // danach alle x Millisekunden
                    PendingIntent.getBroadcast(
                            context,
                            REQESTCODE,
                            intent,
                            (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ?
                                    PendingIntent.FLAG_MUTABLE :
                                    0
                    )
            );
        }
    }

    static private void deleteTimer(Context context) {
        Intent intent = new Intent(context, AutoBackup_Receiver.class);
        intent.setAction(AUTOBACKUP);

        AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        mAlarmManager.cancel(PendingIntent.getBroadcast(
                context,
                REQESTCODE,
                intent,
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)?PendingIntent.FLAG_MUTABLE:0
        ));
    }
}
