/*
 * Copyright (C) 2017 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.carrierdefaultapp;

import android.app.Activity;
import android.app.LoadedApk;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Proxy;
import android.net.TrafficStats;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;

/**
 * Activity that launches in response to the captive portal notification
 * @see com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
 * This activity requests network connection if there is no available one before loading the real
 * portal page and apply carrier actions on the portal activation result.
 */
public class CaptivePortalLoginActivity extends Activity {
    private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
    private static final boolean DBG = true;

    private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
    public static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;

    private URL mUrl;
    private Network mNetwork;
    private NetworkCallback mNetworkCallback;
    private ConnectivityManager mCm;
    private WebView mWebView;
    private MyWebViewClient mWebViewClient;
    private boolean mLaunchBrowser = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCm = ConnectivityManager.from(this);
        mUrl = getUrlForCaptivePortal();
        if (mUrl == null) {
            done(false);
            return;
        }
        if (DBG) logd(String.format("onCreate for %s", mUrl.toString()));
        setContentView(R.layout.activity_captive_portal_login);
        getActionBar().setDisplayShowHomeEnabled(false);

        mWebView = findViewById(R.id.webview);
        mWebView.clearCache(true);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        mWebViewClient = new MyWebViewClient();
        mWebView.setWebViewClient(mWebViewClient);
        mWebView.setWebChromeClient(new MyWebChromeClient());

        mNetwork = getNetworkForCaptivePortal();
        if (mNetwork == null) {
            requestNetworkForCaptivePortal();
        } else {
            mCm.bindProcessToNetwork(mNetwork);
            // Start initial page load so WebView finishes loading proxy settings.
            // Actual load of mUrl is initiated by MyWebViewClient.
            mWebView.loadData("", "text/html", null);
        }
    }

    @Override
    public void onBackPressed() {
        WebView myWebView = findViewById(R.id.webview);
        if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
            myWebView.goBack();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releaseNetworkRequest();
        if (mLaunchBrowser) {
            // Give time for this network to become default. After 500ms just proceed.
            for (int i = 0; i < 5; i++) {
                // TODO: This misses when mNetwork underlies a VPN.
                if (mNetwork.equals(mCm.getActiveNetwork())) break;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
            final String url = mUrl.toString();
            if (DBG) logd("starting activity with intent ACTION_VIEW for " + url);
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        }
    }

    // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
    private void setWebViewProxy() {
        LoadedApk loadedApk = getApplication().mLoadedApk;
        try {
            Field receiversField = LoadedApk.class.getDeclaredField("mReceivers");
            receiversField.setAccessible(true);
            ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
            for (Object receiverMap : receivers.values()) {
                for (Object rec : ((ArrayMap) receiverMap).keySet()) {
                    Class clazz = rec.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(rec, getApplicationContext(), intent);
                        Log.v(TAG, "Prompting WebView proxy reload.");
                    }
                }
            }
        } catch (Exception e) {
            loge("Exception while setting WebView proxy: " + e);
        }
    }

    private void done(boolean success) {
        if (DBG) logd(String.format("Result success %b for %s", success, mUrl.toString()));
        if (success) {
            // Trigger re-evaluation upon success http response code
            CarrierActionUtils.applyCarrierAction(
                    CarrierActionUtils.CARRIER_ACTION_ENABLE_RADIO, getIntent(),
                    getApplicationContext());
            CarrierActionUtils.applyCarrierAction(
                    CarrierActionUtils.CARRIER_ACTION_ENABLE_METERED_APNS, getIntent(),
                    getApplicationContext());
            CarrierActionUtils.applyCarrierAction(
                    CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
                    getApplicationContext());

        }
        finishAndRemoveTask();
    }

    private URL getUrlForCaptivePortal() {
        String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
        if (url.isEmpty()) {
            url = mCm.getCaptivePortalServerUrl();
        }
        final CarrierConfigManager configManager = getApplicationContext()
                .getSystemService(CarrierConfigManager.class);
        final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                SubscriptionManager.getDefaultVoiceSubscriptionId());
        final String[] portalURLs = configManager.getConfigForSubId(subId).getStringArray(
                CarrierConfigManager.KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY);
        if (!ArrayUtils.isEmpty(portalURLs)) {
            for (String portalUrl : portalURLs) {
                if (url.startsWith(portalUrl)) {
                    break;
                }
            }
            url = null;
        }
        try {
            return new URL(url);
        } catch (MalformedURLException e) {
            loge("Invalid captive portal URL " + url);
        }
        return null;
    }

    private void testForCaptivePortal() {
        new Thread(new Runnable() {
            public void run() {
                // Give time for captive portal to open.
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                HttpURLConnection urlConnection = null;
                int httpResponseCode = 500;
                int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
                try {
                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
                    urlConnection.setInstanceFollowRedirects(false);
                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
                    urlConnection.setUseCaches(false);
                    urlConnection.getInputStream();
                    httpResponseCode = urlConnection.getResponseCode();
                } catch (IOException e) {
                } finally {
                    if (urlConnection != null) urlConnection.disconnect();
                    TrafficStats.setThreadStatsTag(oldTag);
                }
                if (httpResponseCode == 204) {
                    done(true);
                }
            }
        }).start();
    }

    private Network getNetworkForCaptivePortal() {
        Network[] info = mCm.getAllNetworks();
        if (!ArrayUtils.isEmpty(info)) {
            for (Network nw : info) {
                final NetworkCapabilities nc = mCm.getNetworkCapabilities(nw);
                if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                        && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
                    return nw;
                }
            }
        }
        return null;
    }

    private void requestNetworkForCaptivePortal() {
        NetworkRequest request = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                .build();

        mNetworkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (DBG) logd("Network available: " + network);
                mCm.bindProcessToNetwork(network);
                mNetwork = network;
                runOnUiThreadIfNotFinishing(() -> {
                    // Start initial page load so WebView finishes loading proxy settings.
                    // Actual load of mUrl is initiated by MyWebViewClient.
                    mWebView.loadData("", "text/html", null);
                });
            }

            @Override
            public void onUnavailable() {
                if (DBG) logd("Network unavailable");
                runOnUiThreadIfNotFinishing(() -> {
                    // Instead of not loading anything in webview, simply load the page and return
                    // HTTP error page in the absence of network connection.
                    mWebView.loadUrl(mUrl.toString());
                });
            }
        };
        logd("request Network for captive portal");
        mCm.requestNetwork(request, mNetworkCallback, NETWORK_REQUEST_TIMEOUT_MS);
    }

    private void releaseNetworkRequest() {
        logd("release Network for captive portal");
        if (mNetworkCallback != null) {
            mCm.unregisterNetworkCallback(mNetworkCallback);
            mNetworkCallback = null;
            mNetwork = null;
        }
    }

    private class MyWebViewClient extends WebViewClient {
        private static final String INTERNAL_ASSETS = "file:///android_asset/";
        private final String mBrowserBailOutToken = Long.toString(new Random().nextLong());
        // How many Android device-independent-pixels per scaled-pixel
        // dp/sp = (px/sp) / (px/dp) = (1/sp) / (1/dp)
        private final float mDpPerSp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
                    getResources().getDisplayMetrics())
                / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
                    getResources().getDisplayMetrics());
        private int mPagesLoaded;

        // If we haven't finished cleaning up the history, don't allow going back.
        public boolean allowBack() {
            return mPagesLoaded > 1;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            if (url.contains(mBrowserBailOutToken)) {
                mLaunchBrowser = true;
                done(false);
                return;
            }
            // The first page load is used only to cause the WebView to
            // fetch the proxy settings.  Don't update the URL bar, and
            // don't check if the captive portal is still there.
            if (mPagesLoaded == 0) return;
            // For internally generated pages, leave URL bar listing prior URL as this is the URL
            // the page refers to.
            if (!url.startsWith(INTERNAL_ASSETS)) {
                final TextView myUrlBar = findViewById(R.id.url_bar);
                myUrlBar.setText(url);
            }
            if (mNetwork != null) {
                testForCaptivePortal();
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            mPagesLoaded++;
            if (mPagesLoaded == 1) {
                // Now that WebView has loaded at least one page we know it has read in the proxy
                // settings.  Now prompt the WebView read the Network-specific proxy settings.
                setWebViewProxy();
                // Load the real page.
                view.loadUrl(mUrl.toString());
                return;
            } else if (mPagesLoaded == 2) {
                // Prevent going back to empty first page.
                view.clearHistory();
            }
            if (mNetwork != null) {
                testForCaptivePortal();
            }
        }

        // Convert Android device-independent-pixels (dp) to HTML size.
        private String dp(int dp) {
            // HTML px's are scaled just like dp's, so just add "px" suffix.
            return Integer.toString(dp) + "px";
        }

        // Convert Android scaled-pixels (sp) to HTML size.
        private String sp(int sp) {
            // Convert sp to dp's.
            float dp = sp * mDpPerSp;
            // Apply a scale factor to make things look right.
            dp *= 1.3;
            // Convert dp's to HTML size.
            return dp((int) dp);
        }

        // A web page consisting of a large broken lock icon to indicate SSL failure.
        private final String SSL_ERROR_HTML = "<html><head><style>"
                + "body { margin-left:" + dp(48) + "; margin-right:" + dp(48) + "; "
                + "margin-top:" + dp(96) + "; background-color:#fafafa; }"
                + "img { width:" + dp(48) + "; height:" + dp(48) + "; }"
                + "div.warn { font-size:" + sp(16) + "; margin-top:" + dp(16) + "; "
                + "           opacity:0.87; line-height:1.28; }"
                + "div.example { font-size:" + sp(14) + "; margin-top:" + dp(16) + "; "
                + "              opacity:0.54; line-height:1.21905; }"
                + "a { font-size:" + sp(14) + "; text-decoration:none; text-transform:uppercase; "
                + "    margin-top:" + dp(24) + "; display:inline-block; color:#4285F4; "
                + "    height:" + dp(48) + "; font-weight:bold; }"
                + "</style></head><body><p><img src=quantum_ic_warning_amber_96.png><br>"
                + "<div class=warn>%s</div>"
                + "<div class=example>%s</div>" + "<a href=%s>%s</a></body></html>";

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            Log.w(TAG, "SSL error (error: " + error.getPrimaryError() + " host: "
                    // Only show host to avoid leaking private info.
                    + Uri.parse(error.getUrl()).getHost() + " certificate: "
                    + error.getCertificate() + "); displaying SSL warning.");
            final String html = String.format(SSL_ERROR_HTML, getString(R.string.ssl_error_warning),
                    getString(R.string.ssl_error_example), mBrowserBailOutToken,
                    getString(R.string.ssl_error_continue));
            view.loadDataWithBaseURL(INTERNAL_ASSETS, html, "text/HTML", "UTF-8", null);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.startsWith("tel:")) {
                startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
                return true;
            }
            return false;
        }
    }

    private class MyWebChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            final ProgressBar myProgressBar = findViewById(R.id.progress_bar);
            myProgressBar.setProgress(newProgress);
        }
    }

    private void runOnUiThreadIfNotFinishing(Runnable r) {
        if (!isFinishing()) {
            runOnUiThread(r);
        }
    }

    private static void logd(String s) {
        Rlog.d(TAG, s);
    }

    private static void loge(String s) {
        Rlog.d(TAG, s);
    }

}
