package com.unibuy.smartdevice.tools;

import android.content.Context;
import com.unibuy.smartdevice.exception.Logs;
import com.unibuy.smartdevice.external.mqtt.MqttManager;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 負責遠端 APK 的背景下載與 Root 靜默覆蓋安裝管理
 */
public class OtaManager {
    private static final String TAG = "OtaManager";
    private static final Logs logs = new Logs(OtaManager.class);
    private static final int DOWNLOAD_CONNECT_TIMEOUT_MS = 30000;
    private static final int DOWNLOAD_READ_TIMEOUT_MS = 120000;

    /**
     * 啟動背景執行緒執行 APP OTA 更新
     *
     * @param context 應用程式 Context
     * @param apkUrl  新版 APK 的下載位址
     * @param cmdId   MQTT 指令 ID，用於回報執行結果
     */
    public static void startUpdate(Context context, String apkUrl, String cmdId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                MqttManager mqttManager = MqttManager.getInstance();
                try {
                    logs.info("Starting OTA update process. URL: " + apkUrl + " (cmdId: " + cmdId + ")");
                    mqttManager.publishCommandAck(cmdId, "success", "Downloading update APK...");

                    // 1. 背景下載 APK 到 APP 私有快取空間
                    File apkFile = downloadApk(context, apkUrl);
                    if (apkFile == null || !apkFile.exists()) {
                        throw new Exception("Downloaded APK file is null or does not exist.");
                    }
                    logs.info("APK downloaded successfully to: " + apkFile.getAbsolutePath());

                    // 2. 執行 Root 靜默安裝
                    mqttManager.publishCommandAck(cmdId, "success", "Installing update APK...");
                    boolean installSuccess = silentInstall(apkFile.getAbsolutePath());

                    if (installSuccess) {
                        logs.info("Silent installation triggered successfully. App should be restarted by BootReceiver soon.");
                        // 安裝成功後，系統會因為 ACTION_MY_PACKAGE_REPLACED 自動重啟主 APP。
                        // 此處已不需要再做其他處理。
                    } else {
                        throw new Exception("Silent installation command returned non-zero status.");
                    }

                } catch (Exception e) {
                    logs.error(com.unibuy.smartdevice.exception.ErrorCode.UNKNOWN_ERROR, "OTA Update failed: " + e.getMessage());
                    mqttManager.publishCommandAck(cmdId, "failed", "OTA Update failed: " + e.getMessage());
                }
            }
        }).start();
    }

    /**
     * 從網路下載 APK 檔案並存入 APP 私有快取目錄中
     */
    private static File downloadApk(Context context, String apkUrl) throws Exception {
        URL url = new URL(apkUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(DOWNLOAD_CONNECT_TIMEOUT_MS);
        connection.setReadTimeout(DOWNLOAD_READ_TIMEOUT_MS);
        connection.connect();

        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new Exception("Server returned HTTP " + connection.getResponseCode()
                    + " " + connection.getResponseMessage());
        }

        // 使用 APP 私有的外部快取目錄，免去 Android 12 的 WRITE_EXTERNAL_STORAGE 權限宣告與申請
        File cacheDir = context.getExternalCacheDir();
        if (cacheDir == null) {
            cacheDir = context.getCacheDir();
        }
        File apkFile = new File(cacheDir, "update_ota.apk");
        if (apkFile.exists()) {
            apkFile.delete();
        }

        try (InputStream input = new BufferedInputStream(connection.getInputStream());
             FileOutputStream output = new FileOutputStream(apkFile)) {

            byte[] data = new byte[4096];
            int count;
            while ((count = input.read(data)) != -1) {
                output.write(data, 0, count);
            }
            output.flush();
        } finally {
            connection.disconnect();
        }
        return apkFile;
    }

    /**
     * 調用 Root 權限執行 pm install -r 靜默安裝
     */
    private static boolean silentInstall(String apkPath) {
        Process process = null;
        DataOutputStream os = null;
        try {
            logs.info("Executing silent install command via su: pm install -r -d " + apkPath);
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes("pm install -r -d " + apkPath + "\n");
            os.writeBytes("exit\n");
            os.flush();

            int exitValue = process.waitFor();
            logs.info("Silent install process exit value: " + exitValue);
            return exitValue == 0;
        } catch (Exception e) {
            logs.info("Failed to execute silent install su command: " + e.getMessage());
            logs.warning(e);
            return false;
        } finally {
            try {
                if (os != null) os.close();
                if (process != null) process.destroy();
            } catch (Exception ignored) {}
        }
    }
}
