package com.foxx.androidcast.vpn;

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

import com.wireguard.android.backend.GoBackend;
import com.wireguard.android.backend.Tunnel;
import com.wireguard.config.Config;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

/** WireGuard tunnel control inside the :vpn process only. */
final class WireGuardVpnEngine {
    private static final String TAG = "WireGuardVpnEngine";
    private static final Tunnel ANDROID_CAST_TUNNEL = new Tunnel() {
        @Override
        public String getName() {
            return "androidcast-ra";
        }

        @Override
        public void onStateChange(State newState) {
            Log.d(TAG, "tunnel state " + newState);
        }
    };

    private WireGuardVpnEngine() {}

    static boolean apply(Context context, String wgQuickConfig) {
        if (wgQuickConfig == null || wgQuickConfig.trim().isEmpty()) {
            return false;
        }
        try {
            Config config;
            try (ByteArrayInputStream in = new ByteArrayInputStream(
                    wgQuickConfig.getBytes(StandardCharsets.UTF_8))) {
                config = Config.parse(in);
            }
            GoBackend backend = new GoBackend(context);
            backend.setState(ANDROID_CAST_TUNNEL, Tunnel.State.UP, config);
            Log.i(TAG, "wireguard UP via GoBackend");
            return true;
        } catch (Throwable t) {
            Log.w(TAG, "GoBackend failed, TUN fallback: " + t.getMessage());
            return RemoteAccessVpnService.startWithConfig(context, wgQuickConfig);
        }
    }

    static void tearDown(Context context) {
        RemoteAccessVpnService.stop(context);
        try {
            GoBackend backend = new GoBackend(context);
            backend.setState(ANDROID_CAST_TUNNEL, Tunnel.State.DOWN, null);
        } catch (Throwable ignored) {
        }
    }
}
