package org.iiab.controller;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * A stateless utility class to perform keep-alive actions for Termux.
 * The lifecycle (start/stop/loop) is managed by the calling service.
 */
public class IIABWatchdog {
    private static final String TAG = "IIAB-Controller";

    public static final String ACTION_LOG_MESSAGE = "org.iiab.controller.LOG_MESSAGE";
    public static final String EXTRA_MESSAGE = "org.iiab.controller.EXTRA_MESSAGE";

    // --- TEMPORARY DEBUG FLAGS ---
    private static final boolean DEBUG_ENABLED = true;
    private static final String BLACKBOX_FILE = "watchdog_heartbeat_log.txt";
    // ----------------------------

    /**
     * Performs a full heartbeat pulse: sending stimulus and debug ping.
     */
    public static void performHeartbeat(Context context) {
        sendStimulus(context);
        performDebugPing(context);
    }

    /**
     * Sends a command to Termux to keep it active.
     * This is the real keep-alive mechanism.
     * @param context The context to use for sending the intent.
     */
    public static void sendStimulus(Context context) {
        if (DEBUG_ENABLED) {
            writeToBlackBox(context, "Sending Intent (true) to Termux to keep it awake...");
        }

        Intent intent = new Intent("com.termux.service.RUN_COMMAND");
        intent.setClassName("com.termux", "com.termux.app.RunCommandService");
        intent.putExtra("com.termux.service.RUN_COMMAND_PATH", "/data/data/com.termux/files/usr/bin/true");
        intent.putExtra("com.termux.service.RUN_COMMAND_BACKGROUND", true);

        try {
            context.startService(intent);
        } catch (Exception e) {
            if (DEBUG_ENABLED) {
                Log.e(TAG, "[DEBUG_DEEP_SLEEP] Failed to send 'true' command to Termux", e);
                writeToBlackBox(context, "ERROR sending Intent: " + e.getMessage());
            }
        }
    }

    /**
     * Pings the Termux NGINX server to check if it's responsive.
     * This is a temporary debugging tool.
     * // TODO: REMOVE AFTER HANS DEBUGGING
     * @param context The context for writing to the blackbox log.
     */
    public static void performDebugPing(Context context) {
        final String NGINX_IP = "127.0.0.1";
        final int NGINX_PORT = 8085;

        new Thread(() -> {
            try (Socket socket = new Socket()) {
                socket.connect(new InetSocketAddress(NGINX_IP, NGINX_PORT), 2000);
                if (DEBUG_ENABLED) {
                    Log.e(TAG, "[DEBUG_DEEP_SLEEP] PING 8085 SUCCESSFUL: Termux is alive.");
                    writeToBlackBox(context, "PING 8085 SUCCESSFUL: Termux is alive.");
                }
            } catch (IOException e) {
                if (DEBUG_ENABLED) {
                    Log.w(TAG, "[DEBUG_DEEP_SLEEP] PING 8085 FAILED: " + e.getMessage());
                    writeToBlackBox(context, "PING 8085 FAILED: " + e.getMessage());
                }
            }
        }).start();
    }

    public static void logSessionStart(Context context) {
        if (DEBUG_ENABLED) {
            writeToBlackBox(context, "HEARTBEAT SESSION STARTED (Thread based)");
        }
    }

    public static void logSessionStop(Context context) {
        if (DEBUG_ENABLED) {
            writeToBlackBox(context, "HEARTBEAT SESSION STOPPED");
        }
    }

    private static void writeToBlackBox(Context context, String message) {
        try {
            File logFile = new File(context.getFilesDir(), BLACKBOX_FILE);
            FileWriter writer = new FileWriter(logFile, true);
            String datePrefix = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date());
            writer.append(datePrefix).append(" - ").append(message).append("\n");
            writer.close();

            // Also broadcast for UI update
            broadcastLog(context, message);
        } catch (IOException e) {
            Log.e(TAG, "Failed to write to BlackBox", e);
        }
    }

    private static void broadcastLog(Context context, String message) {
        Intent intent = new Intent(ACTION_LOG_MESSAGE);
        intent.putExtra(EXTRA_MESSAGE, message);
        context.sendBroadcast(intent);
    }
}
