package com.foxx.androidcast.dev;

import android.text.TextUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/** Snapshot of wireless adb endpoints for rebuild.sh / curl when adb is down. */
public final class DevAdbConnectInfo {
    public static final int HTTP_PORT = 5039;
    public static final int LEGACY_TCP_PORT = 5555;
    public static final String LOG_TAG = "DevAdbConnect";
    public static final String ACTION_REFRESH = "com.foxx.androidcast.dev.REFRESH_ADB_WIFI";
    public static final String RELATIVE_JSON_PATH = "dev/adb_connect.json";

    public final List<String> ips;
    public final List<String> connect;
    public final boolean adbEnabled;
    public final boolean adbWifiEnabled;
    public final boolean secureSettingsGranted;
    public final int legacyPort;
    public final long updatedMs;

    public DevAdbConnectInfo(
            List<String> ips,
            List<String> connect,
            boolean adbEnabled,
            boolean adbWifiEnabled,
            boolean secureSettingsGranted,
            int legacyPort,
            long updatedMs) {
        this.ips = ips != null ? ips : Collections.emptyList();
        this.connect = connect != null ? connect : Collections.emptyList();
        this.adbEnabled = adbEnabled;
        this.adbWifiEnabled = adbWifiEnabled;
        this.secureSettingsGranted = secureSettingsGranted;
        this.legacyPort = legacyPort;
        this.updatedMs = updatedMs;
    }

    public String primaryConnectLine() {
        return connect.isEmpty() ? "" : connect.get(0);
    }

    public String toJson() {
        try {
            JSONObject root = new JSONObject();
            root.put("package", "com.foxx.androidcast");
            root.put("http_port", HTTP_PORT);
            root.put("legacy_port", legacyPort);
            root.put("adb_enabled", adbEnabled);
            root.put("adb_wifi_enabled", adbWifiEnabled);
            root.put("secure_settings_granted", secureSettingsGranted);
            root.put("updated_ms", updatedMs);
            root.put("ips", toJsonArray(ips));
            root.put("connect", toJsonArray(connect));
            root.put("tls_port",
                    findFirstNonLegacyPort(connect));
            root.put("needs_secure_grant", !secureSettingsGranted);
            JSONArray commands = new JSONArray();
            for (String endpoint : connect) {
                if (!TextUtils.isEmpty(endpoint)) {
                    commands.put("adb connect " + endpoint);
                }
            }
            root.put("commands", commands);
            root.put("hint", "Grant WRITE_SECURE_SETTINGS once via USB; use tls_port "
                    + "(not 5555) on Android 11+. Host: avahi-browse -rpt _adb-tls-connect._tcp");
            return root.toString(2);
        } catch (JSONException e) {
            return "{}";
        }
    }

    public String toLogLine() {
        return "ADB_JSON " + toJson().replace('\n', ' ');
    }

    private static int findFirstNonLegacyPort(List<String> connect) {
        for (String endpoint : connect) {
            if (TextUtils.isEmpty(endpoint) || !endpoint.contains(":")) {
                continue;
            }
            int port = parsePort(endpoint);
            if (port > 0 && port != LEGACY_TCP_PORT) {
                return port;
            }
        }
        return -1;
    }

    private static int parsePort(String endpoint) {
        int idx = endpoint.lastIndexOf(':');
        if (idx < 0) {
            return -1;
        }
        try {
            return Integer.parseInt(endpoint.substring(idx + 1));
        } catch (NumberFormatException e) {
            return -1;
        }
    }

    private static JSONArray toJsonArray(List<String> values) {
        JSONArray array = new JSONArray();
        for (String value : values) {
            if (!TextUtils.isEmpty(value)) {
                array.put(value);
            }
        }
        return array;
    }

    public static List<String> mergeEndpoints(List<String> ips, List<Integer> ports) {
        Set<String> out = new LinkedHashSet<>();
        for (String ip : ips) {
            if (TextUtils.isEmpty(ip)) {
                continue;
            }
            for (Integer port : ports) {
                if (port != null && port > 0 && port < 65536) {
                    out.add(ip + ":" + port);
                }
            }
        }
        return new ArrayList<>(out);
    }
}
