package com.secureline.server;

import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.PowerManager;
import android.os.RecoverySystem;
import android.os.UserHandle;
import android.util.Slog;

import com.android.server.locksettings.SecureLineDuressBridge;

import java.util.concurrent.atomic.AtomicBoolean;

public final class SecureLineWipe {

    private static final String TAG = "SecureLineWipe";

    private static final AtomicBoolean WIPE_STARTED =
            new AtomicBoolean(false);

    private SecureLineWipe() {}

    public static void trigger(Context context, String reason) {

        if (!WIPE_STARTED.compareAndSet(false, true)) {

            Slog.w(TAG,
                "wipe already running, ignoring duplicate trigger: "
                + reason);

            return;
        }

        final String wipeReason =
                "SecureLine:" + reason;

        new Thread("SecureLine-Wipe") {

            @Override
            public void run() {

                final long token =
                        Binder.clearCallingIdentity();

                try {

                    Slog.e(TAG,
                        "SECURE WIPE STARTED: "
                        + wipeReason);

                    /*
                     PRIMARY PATH
                     GrapheneOS crypto wipe
                    */

                    SecureLineDuressBridge.run(context);

                    /*
                     should normally never return
                    */

                    Slog.wtf(TAG,
                        "DuressWipe returned unexpectedly");

                }
                catch (Throwable primaryFailure) {

                    Slog.e(TAG,
                        "Primary wipe failed",
                        primaryFailure);
                }

                /*
                 fallback chain
                */

                try {

                    Slog.e(TAG,
                        "Fallback → recovery wipe");

                    RecoverySystem.rebootWipeUserData(
                            context,
                            false,
                            wipeReason,
                            true,
                            true,
                            false
                    );

                    return;

                }
                catch (Throwable recoveryFailure) {

                    Slog.e(TAG,
                        "Recovery wipe failed",
                        recoveryFailure);
                }

                try {

                    Slog.e(TAG,
                        "Fallback → broadcast reset");

                    Intent resetIntent =
                            new Intent(
                                Intent.ACTION_FACTORY_RESET);

                    resetIntent.setPackage("android");

                    resetIntent.addFlags(
                        Intent.FLAG_RECEIVER_FOREGROUND);

                    resetIntent.putExtra(
                        Intent.EXTRA_REASON,
                        wipeReason);

                    resetIntent.putExtra(
                        Intent.EXTRA_WIPE_EXTERNAL_STORAGE,
                        true);

                    context.sendBroadcastAsUser(
                        resetIntent,
                        UserHandle.SYSTEM);

                    return;

                }
                catch (Throwable broadcastFailure) {

                    Slog.e(TAG,
                        "Broadcast reset failed",
                        broadcastFailure);
                }

                try {

                    Slog.e(TAG,
                        "Final fallback → reboot recovery");

                    PowerManager pm =
                        (PowerManager)
                            context.getSystemService(
                                Context.POWER_SERVICE);

                    if (pm != null) {

                        pm.reboot("recovery");
                    }

                }
                catch (Throwable rebootFailure) {

                    Slog.e(TAG,
                        "Recovery reboot failed",
                        rebootFailure);
                }
                finally {

                    Binder.restoreCallingIdentity(token);
                }
            }

        }.start();
    }
}
