/**
 * Copyright (c) 2018, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.connectivity;

import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST;
import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_HOST;
import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PAC;
import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PORT;
import static android.provider.Settings.Global.HTTP_PROXY;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Proxy;
import android.net.ProxyInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;

import java.util.Objects;

/**
 * A class to handle proxy for ConnectivityService.
 *
 * @hide
 */
public class ProxyTracker {
    private static final String TAG = ProxyTracker.class.getSimpleName();
    private static final boolean DBG = true;

    @NonNull
    private final Context mContext;

    @NonNull
    private final Object mProxyLock = new Object();
    // The global proxy is the proxy that is set device-wide, overriding any network-specific
    // proxy. Note however that proxies are hints ; the system does not enforce their use. Hence
    // this value is only for querying.
    @Nullable
    @GuardedBy("mProxyLock")
    private ProxyInfo mGlobalProxy = null;
    // The default proxy is the proxy that applies to no particular network if the global proxy
    // is not set. Individual networks have their own settings that override this. This member
    // is set through setDefaultProxy, which is called when the default network changes proxies
    // in its LinkProperties, or when ConnectivityService switches to a new default network, or
    // when PacManager resolves the proxy.
    @Nullable
    @GuardedBy("mProxyLock")
    private volatile ProxyInfo mDefaultProxy = null;
    // Whether the default proxy is enabled.
    @GuardedBy("mProxyLock")
    private boolean mDefaultProxyEnabled = true;

    // The object responsible for Proxy Auto Configuration (PAC).
    @NonNull
    private final PacManager mPacManager;

    public ProxyTracker(@NonNull final Context context,
            @NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) {
        mContext = context;
        mPacManager = new PacManager(context, connectivityServiceInternalHandler, pacChangedEvent);
    }

    // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
    // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
    // proxy is null then there is no proxy in place).
    @Nullable
    private static ProxyInfo canonicalizeProxyInfo(@Nullable final ProxyInfo proxy) {
        if (proxy != null && TextUtils.isEmpty(proxy.getHost())
                && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
            return null;
        }
        return proxy;
    }

    // ProxyInfo equality functions with a couple modifications over ProxyInfo.equals() to make it
    // better for determining if a new proxy broadcast is necessary:
    // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
    //    avoid unnecessary broadcasts.
    // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
    //    is in place.  This is important so legacy PAC resolver (see com.android.proxyhandler)
    //    changes aren't missed.  The legacy PAC resolver pretends to be a simple HTTP proxy but
    //    actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
    //    all set.
    public static boolean proxyInfoEqual(@Nullable final ProxyInfo a, @Nullable final ProxyInfo b) {
        final ProxyInfo pa = canonicalizeProxyInfo(a);
        final ProxyInfo pb = canonicalizeProxyInfo(b);
        // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
        // hosts even when PAC URLs are present to account for the legacy PAC resolver.
        return Objects.equals(pa, pb) && (pa == null || Objects.equals(pa.getHost(), pb.getHost()));
    }

    /**
     * Gets the default system-wide proxy.
     *
     * This will return the global proxy if set, otherwise the default proxy if in use. Note
     * that this is not necessarily the proxy that any given process should use, as the right
     * proxy for a process is the proxy for the network this process will use, which may be
     * different from this value. This value is simply the default in case there is no proxy set
     * in the network that will be used by a specific process.
     * @return The default system-wide proxy or null if none.
     */
    @Nullable
    public ProxyInfo getDefaultProxy() {
        // This information is already available as a world read/writable jvm property.
        synchronized (mProxyLock) {
            if (mGlobalProxy != null) return mGlobalProxy;
            if (mDefaultProxyEnabled) return mDefaultProxy;
            return null;
        }
    }

    /**
     * Gets the global proxy.
     *
     * @return The global proxy or null if none.
     */
    @Nullable
    public ProxyInfo getGlobalProxy() {
        // This information is already available as a world read/writable jvm property.
        synchronized (mProxyLock) {
            return mGlobalProxy;
        }
    }

    /**
     * Read the global proxy settings and cache them in memory.
     */
    public void loadGlobalProxy() {
        ContentResolver res = mContext.getContentResolver();
        String host = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_HOST);
        int port = Settings.Global.getInt(res, GLOBAL_HTTP_PROXY_PORT, 0);
        String exclList = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
        String pacFileUrl = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_PAC);
        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
            ProxyInfo proxyProperties;
            if (!TextUtils.isEmpty(pacFileUrl)) {
                proxyProperties = new ProxyInfo(pacFileUrl);
            } else {
                proxyProperties = new ProxyInfo(host, port, exclList);
            }
            if (!proxyProperties.isValid()) {
                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
                return;
            }

            synchronized (mProxyLock) {
                mGlobalProxy = proxyProperties;
            }
        }
        loadDeprecatedGlobalHttpProxy();
        // TODO : shouldn't this function call mPacManager.setCurrentProxyScriptUrl ?
    }

    /**
     * Read the global proxy from the deprecated Settings.Global.HTTP_PROXY setting and apply it.
     */
    public void loadDeprecatedGlobalHttpProxy() {
        final String proxy = Settings.Global.getString(mContext.getContentResolver(), HTTP_PROXY);
        if (!TextUtils.isEmpty(proxy)) {
            String data[] = proxy.split(":");
            if (data.length == 0) {
                return;
            }

            final String proxyHost = data[0];
            int proxyPort = 8080;
            if (data.length > 1) {
                try {
                    proxyPort = Integer.parseInt(data[1]);
                } catch (NumberFormatException e) {
                    return;
                }
            }
            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
            setGlobalProxy(p);
        }
    }

    /**
     * Sends the system broadcast informing apps about a new proxy configuration.
     *
     * Confusingly this method also sets the PAC file URL. TODO : separate this, it has nothing
     * to do in a "sendProxyBroadcast" method.
     */
    public void sendProxyBroadcast() {
        final ProxyInfo defaultProxy = getDefaultProxy();
        final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
        if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)
                == PacManager.ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST) {
            return;
        }
        if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
                Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxyInfo);
        final long ident = Binder.clearCallingIdentity();
        try {
            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /**
     * Sets the global proxy in memory. Also writes the values to the global settings of the device.
     *
     * @param proxyInfo the proxy spec, or null for no proxy.
     */
    public void setGlobalProxy(@Nullable ProxyInfo proxyInfo) {
        synchronized (mProxyLock) {
            // ProxyInfo#equals is not commutative :( and is public API, so it can't be fixed.
            if (proxyInfo == mGlobalProxy) return;
            if (proxyInfo != null && proxyInfo.equals(mGlobalProxy)) return;
            if (mGlobalProxy != null && mGlobalProxy.equals(proxyInfo)) return;

            final String host;
            final int port;
            final String exclList;
            final String pacFileUrl;
            if (proxyInfo != null && (!TextUtils.isEmpty(proxyInfo.getHost()) ||
                    !Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))) {
                if (!proxyInfo.isValid()) {
                    if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                    return;
                }
                mGlobalProxy = new ProxyInfo(proxyInfo);
                host = mGlobalProxy.getHost();
                port = mGlobalProxy.getPort();
                exclList = mGlobalProxy.getExclusionListAsString();
                pacFileUrl = Uri.EMPTY.equals(proxyInfo.getPacFileUrl())
                        ? "" : proxyInfo.getPacFileUrl().toString();
            } else {
                host = "";
                port = 0;
                exclList = "";
                pacFileUrl = "";
                mGlobalProxy = null;
            }
            final ContentResolver res = mContext.getContentResolver();
            final long token = Binder.clearCallingIdentity();
            try {
                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_HOST, host);
                Settings.Global.putInt(res, GLOBAL_HTTP_PROXY_PORT, port);
                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclList);
                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
            } finally {
                Binder.restoreCallingIdentity(token);
            }

            sendProxyBroadcast();
        }
    }

    /**
     * Sets the default proxy for the device.
     *
     * The default proxy is the proxy used for networks that do not have a specific proxy.
     * @param proxyInfo the proxy spec, or null for no proxy.
     */
    public void setDefaultProxy(@Nullable ProxyInfo proxyInfo) {
        synchronized (mProxyLock) {
            if (Objects.equals(mDefaultProxy, proxyInfo)) return;
            if (proxyInfo != null &&  !proxyInfo.isValid()) {
                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                return;
            }

            // This call could be coming from the PacManager, containing the port of the local
            // proxy. If this new proxy matches the global proxy then copy this proxy to the
            // global (to get the correct local port), and send a broadcast.
            // TODO: Switch PacManager to have its own message to send back rather than
            // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
            if ((mGlobalProxy != null) && (proxyInfo != null)
                    && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
                    && proxyInfo.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
                mGlobalProxy = proxyInfo;
                sendProxyBroadcast();
                return;
            }
            mDefaultProxy = proxyInfo;

            if (mGlobalProxy != null) return;
            if (mDefaultProxyEnabled) {
                sendProxyBroadcast();
            }
        }
    }
}
