package com.okithaki.autoapp;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.webkit.CookieManager;
import android.webkit.WebView;

import org.json.JSONObject;

import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * OK ITHAKI V249436 application-specific private relay.
 *
 * This is not a claim of full Tor equivalence. The client loads the complete ITHAKI
 * web application from a user-controlled HTTPS reverse relay. A relay chain can be
 * configured server-side, but meaningful separation requires independent hosts.
 */
public final class IthakiPrivateRelayV249436 {
    private static final String PREFS = "ok_ithaki_prefs";
    private static final String KEY_ENABLED = "private_relay_enabled_v249436";
    private static final String KEY_ENTRY = "private_relay_entry_v249436";
    private static final String KEY_CODE = "private_relay_access_v249436";
    private static final String KEY_STRICT = "private_relay_strict_v249436";

    private IthakiPrivateRelayV249436() { }

    private static SharedPreferences prefs(Context c) {
        return c.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
    }

    public static boolean isEnabled(Context c) {
        return prefs(c).getBoolean(KEY_ENABLED, false) && !entryBase(c).isEmpty();
    }

    public static boolean isStrict(Context c) {
        return isEnabled(c) && prefs(c).getBoolean(KEY_STRICT, true);
    }

    public static String entryBase(Context c) {
        return cleanBase(prefs(c).getString(KEY_ENTRY, ""));
    }

    public static String accessCode(Context c) {
        return prefs(c).getString(KEY_CODE, "");
    }

    public static String cleanBase(String raw) {
        if (raw == null) return "";
        String v = raw.trim();
        while (v.endsWith("/")) v = v.substring(0, v.length() - 1);
        return v;
    }

    private static String validationReason(String raw) {
        try {
            String v = cleanBase(raw);
            Uri u = Uri.parse(v);
            if (!"https".equalsIgnoreCase(u.getScheme())) return "https_required";
            if (u.getHost() == null || u.getHost().trim().isEmpty()) return "host_required";
            if (u.getUserInfo() != null && !u.getUserInfo().isEmpty()) return "url_credentials_not_allowed";
            if (u.getQuery() != null || u.getFragment() != null) return "base_url_only";
            return "";
        } catch (Exception e) {
            return "invalid_url";
        }
    }

    public static JSONObject enable(Context c, String entry, String code, boolean strict) {
        JSONObject o = new JSONObject();
        try {
            String reason = validationReason(entry);
            if (!reason.isEmpty()) {
                o.put("ok", false); o.put("reason", reason); return o;
            }
            String clean = cleanBase(entry);
            prefs(c).edit()
                    .putBoolean(KEY_ENABLED, true)
                    .putString(KEY_ENTRY, clean)
                    .putString(KEY_CODE, code == null ? "" : code)
                    .putBoolean(KEY_STRICT, strict)
                    .apply();
            o.put("ok", true);
            o.put("enabled", true);
            o.put("entry_base", clean);
            o.put("strict", strict);
            o.put("full_tor_equivalent", false);
            o.put("independent_nodes_required", true);
            o.put("transport", "ithaki_https_reverse_relay_v249436");
        } catch (Exception e) {
            try { o.put("ok", false); o.put("reason", "save_failed"); } catch (Exception ignored) { }
        }
        return o;
    }

    public static JSONObject disable(Context c) {
        JSONObject o = new JSONObject();
        try {
            prefs(c).edit().putBoolean(KEY_ENABLED, false).apply();
            o.put("ok", true); o.put("enabled", false);
        } catch (Exception e) {
            try { o.put("ok", false); o.put("reason", "disable_failed"); } catch (Exception ignored) { }
        }
        return o;
    }

    public static JSONObject status(Context c) {
        JSONObject o = new JSONObject();
        try {
            o.put("ok", true);
            o.put("enabled", isEnabled(c));
            o.put("strict", isStrict(c));
            o.put("entry_base", entryBase(c));
            o.put("access_code_set", !accessCode(c).isEmpty());
            o.put("full_tor_equivalent", false);
            o.put("independent_nodes_required", true);
            o.put("webrtc_and_fcm_blocked_in_strict_mode", isStrict(c));
            o.put("truth", "App-specific HTTPS private relay. Full Tor equivalence is not claimed.");
        } catch (Exception ignored) { }
        return o;
    }

    public static void applyAccessCookie(Context c, WebView webView) {
        if (!isEnabled(c) || webView == null) return;
        try {
            String base = entryBase(c);
            String code = accessCode(c);
            CookieManager cm = CookieManager.getInstance();
            cm.setAcceptCookie(true);
            cm.setAcceptThirdPartyCookies(webView, false);
            String encoded = URLEncoder.encode(code == null ? "" : code, StandardCharsets.UTF_8.name());
            cm.setCookie(base, "ithaki_relay_access=" + encoded + "; Path=/; Secure; SameSite=Strict");
            cm.flush();
        } catch (Exception ignored) { }
    }

    public static JSONObject test(String entry, String code) {
        JSONObject o = new JSONObject();
        HttpURLConnection conn = null;
        try {
            String reason = validationReason(entry);
            if (!reason.isEmpty()) { o.put("ok", false); o.put("reason", reason); return o; }
            URL url = new URL(cleanBase(entry) + "/relay/v1/health");
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/json");
            if (code != null && !code.isEmpty()) {
                conn.setRequestProperty("Cookie", "ithaki_relay_access=" + URLEncoder.encode(code, "UTF-8"));
            }
            int status = conn.getResponseCode();
            o.put("ok", status >= 200 && status < 300);
            o.put("http_status", status);
            o.put("entry_base", cleanBase(entry));
            if (!(status >= 200 && status < 300)) o.put("reason", "relay_http_" + status);
        } catch (Exception e) {
            try { o.put("ok", false); o.put("reason", "relay_unreachable"); } catch (Exception ignored) { }
        } finally {
            if (conn != null) conn.disconnect();
        }
        return o;
    }
}
