package jp.hazuki.yuzubrowser.webkit;

import android.content.Context;
import android.content.Intent;
import android.net.Proxy;
import android.util.ArrayMap;
import android.widget.Toast;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jp.hazuki.yuzubrowser.BrowserApplication;
import jp.hazuki.yuzubrowser.R;
import jp.hazuki.yuzubrowser.utils.Logger;

public class WebViewProxy {
    private static final Pattern pattern = Pattern.compile("\\s*(.+?):(\\d+)\\s*");

    public static boolean resetProxy(Context context) {
        return setProxy(context, "", 0);
    }

    public static boolean setProxy(Context context, String host, int port) {
        System.setProperty("http.proxyHost", host);
        System.setProperty("http.proxyPort", Integer.toString(port));
        System.setProperty("https.proxyHost", host);
        System.setProperty("https.proxyPort", Integer.toString(port));
        try {
            Class applictionClass = Class.forName("android.app.Application");
            Field mLoadedApkField = applictionClass.getDeclaredField("mLoadedApk");
            mLoadedApkField.setAccessible(true);
            Object mloadedApk = mLoadedApkField.get(context);
            Class loadedApkClass = Class.forName("android.app.LoadedApk");
            Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");
            mReceiversField.setAccessible(true);
            ArrayMap receivers = (ArrayMap) mReceiversField.get(mloadedApk);
            for (Object receiverMap : receivers.values()) {
                for (Object receiver : ((ArrayMap) receiverMap).keySet()) {
                    Class<?> clazz = receiver.getClass();
                    if (clazz.getName().contains("ProxyChangeListener")) {
                        Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
                        onReceiveMethod.invoke(receiver, context, intent);
                    }
                }
            }
            return true;
        } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            Logger.d("ProxySettings", "Exception setting WebKit proxy on Lollipop through ProxyChangeListener: " + e.toString());
        }
        return false;
    }

    public static boolean setProxy(Context context, boolean enable, String proxy_address) {
        if (!WebViewProxy.resetProxy(BrowserApplication.getInstance()))
            return false;

        if (enable) {
            Matcher matcher = pattern.matcher(proxy_address);
            if (matcher.find()) {
                return WebViewProxy.setProxy(BrowserApplication.getInstance(), matcher.group(1), Integer.parseInt(matcher.group(2), 10));
            } else {
                Toast.makeText(context, R.string.proxy_address_error, Toast.LENGTH_LONG).show();
                return false;
            }
        }

        return true;
    }
}

@@ -601,16 +601,62 @@
 %5Cs*%22);%0A%0A
+    private static boolean setProxy = false;%0A%0A
     publ
@@ -2403,16 +2403,39 @@
 ception 
+%7C NullPointerException 
 e) %7B%0A   
@@ -2557,24 +2557,54 @@
 oString());%0A
+            setProxy = false;%0A
         %7D%0A  
@@ -2734,16 +2734,28 @@
     if (
+setProxy && 
 !WebView
@@ -2829,24 +2829,51 @@
 urn false;%0A%0A
+        setProxy = false;%0A%0A
         if (
@@ -2974,24 +2974,57 @@
 r.find()) %7B%0A
+                setProxy = true;%0A
             

fix proxy bug