package com.foxx.androidcast.remoteaccess;

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

/**
 * Optional integration with wireguard-android tunnel module (third-party/wireguard-android).
 * Falls back to {@link RemoteAccessVpnService} TUN setup when module is absent.
 */
public final class WireGuardTunnelBridge {
    private static final String TAG = "WGTunnelBridge";

    private WireGuardTunnelBridge() {}

    public static boolean applyConfig(Context context, String wgQuickConfig) {
        if (wgQuickConfig == null || wgQuickConfig.trim().isEmpty()) {
            return false;
        }
        try {
            Class<?> configClass = Class.forName("com.wireguard.config.Config");
            Object config = configClass.getMethod("parse", String.class).invoke(null, wgQuickConfig);
            Class<?> goBackendClass = Class.forName("com.wireguard.android.backend.GoBackend");
            Object backend = goBackendClass.getConstructor(Context.class).newInstance(context);
            Class<?> tunnelClass = Class.forName("com.wireguard.android.backend.Tunnel");
            Object tunnel = proxyTunnel(tunnelClass);
            Class<?> stateClass = Class.forName("com.wireguard.android.backend.Tunnel$State");
            Object up = enumConstant(stateClass, "UP");
            goBackendClass.getMethod("setState", tunnelClass, stateClass, configClass)
                    .invoke(backend, tunnel, up, config);
            Log.i(TAG, "wireguard tunnel UP via GoBackend");
            return true;
        } catch (Throwable t) {
            Log.i(TAG, "GoBackend unavailable, using VpnService fallback: " + t.getClass().getSimpleName());
            return RemoteAccessVpnService.startWithConfig(context, wgQuickConfig);
        }
    }

    public static void tearDown(Context context) {
        RemoteAccessVpnService.stop(context);
        try {
            Class<?> goBackendClass = Class.forName("com.wireguard.android.backend.GoBackend");
            Object backend = goBackendClass.getConstructor(Context.class).newInstance(context);
            Class<?> tunnelClass = Class.forName("com.wireguard.android.backend.Tunnel");
            Object tunnel = proxyTunnel(tunnelClass);
            Class<?> stateClass = Class.forName("com.wireguard.android.backend.Tunnel$State");
            Object down = enumConstant(stateClass, "DOWN");
            goBackendClass.getMethod("setState", tunnelClass, stateClass, Class.forName("com.wireguard.config.Config"))
                    .invoke(backend, tunnel, down, null);
        } catch (Throwable ignored) {
        }
    }

    private static Object proxyTunnel(Class<?> tunnelClass) {
        return java.lang.reflect.Proxy.newProxyInstance(
                tunnelClass.getClassLoader(),
                new Class<?>[]{tunnelClass},
                (proxy, method, args) -> "getName".equals(method.getName()) ? "androidcast-ra" : null);
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    private static Object enumConstant(Class<?> stateClass, String name) {
        return Enum.valueOf((Class<? extends Enum>) stateClass, name);
    }
}
