/*
 * Copyright 2019 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.example.androidx.webkit;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.webkit.SafeBrowsingResponseCompat;
import androidx.webkit.WebViewClientCompat;
import androidx.webkit.WebViewFeature;

/**
 * An {@link Activity} which shows a custom interstitial if {@link WebView} encounters malicious
 * resources. This class contains the logic for responding to user interaction with custom
 * interstitials. The UI for these interstitials is implemented by {@link
 * PopupInterstitialActivity}.
 */
public class CustomInterstitialActivity extends AppCompatActivity {

    private WebView mWebView;
    private CustomInterstitialWebViewClient mWebViewClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_interstitial);
        setTitle(R.string.custom_interstitial_activity_title);
        WebkitHelpers.appendWebViewVersionToTitle(this);

        if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_HIT)
                && WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED)
                && WebViewFeature.isFeatureSupported(
                        WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) {
            mWebView = findViewById(R.id.custom_interstitial_webview);
            mWebViewClient = new CustomInterstitialWebViewClient(this);
            mWebView.setWebViewClient(mWebViewClient);
            mWebView.loadUrl(SafeBrowsingHelpers.TEST_SAFE_BROWSING_SITE);
        } else {
            WebkitHelpers.showMessageInActivity(this, R.string.webkit_api_not_available);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        mWebViewClient.handleInterstitialResponse(requestCode, resultCode, data);
    }

    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
        } else {
            super.onBackPressed();
        }
    }

    private static class CustomInterstitialWebViewClient extends WebViewClientCompat {
        private Activity mActivity;
        private SparseArray<SafeBrowsingResponseCompat> mSafeBrowsingResponseMap;
        int mActivityRequestCounter;

        CustomInterstitialWebViewClient(Activity activity) {
            mActivity = activity;
            mSafeBrowsingResponseMap = new SparseArray<>();
            mActivityRequestCounter = 0;
        }

        @Override
        @RequiresApi(21) // This won't be called on < L, so we can safely apply @RequiresApi.
        public void onSafeBrowsingHit(@NonNull WebView view,
                @NonNull WebResourceRequest request, int threatType,
                @NonNull SafeBrowsingResponseCompat callback) {
            mSafeBrowsingResponseMap.put(mActivityRequestCounter, callback);
            createInterstitial(threatType, request);
            mActivityRequestCounter++;
        }

        @RequiresApi(21) // for WebResourceRequest
        private void createInterstitial(int threatType, @NonNull WebResourceRequest request) {
            Intent myIntent = new Intent(mActivity, PopupInterstitialActivity.class);
            myIntent.putExtra(PopupInterstitialActivity.THREAT_TYPE, threatType);
            myIntent.putExtra(PopupInterstitialActivity.THREAT_URL, request.getUrl().toString());
            mActivity.startActivityForResult(myIntent, mActivityRequestCounter);
        }

        void handleInterstitialResponse(int requestCode, int resultCode, Intent data) {
            // Get the correct SafeBrowsingResponse for the given interstitial Intent (there can be
            // multiple Intents at the same time if multiple resources are malicious).
            final SafeBrowsingResponseCompat response = mSafeBrowsingResponseMap.get(requestCode);
            mSafeBrowsingResponseMap.delete(requestCode);

            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                if (response == null) {
                    return;
                }

                // Figure out what navigation action we should take.
                String result = data.getStringExtra(PopupInterstitialActivity.ACTION_RESPONSE);
                // Figure out whether we should report this event.
                boolean shouldSendReport = data.getBooleanExtra(
                        PopupInterstitialActivity.SHOULD_SEND_REPORT, false);

                switch (result) {
                    case PopupInterstitialActivity.ACTION_RESPONSE_BACK_TO_SAFETY:
                        response.backToSafety(shouldSendReport);
                        break;
                    case PopupInterstitialActivity.ACTION_RESPONSE_PROCEED:
                        response.proceed(shouldSendReport);
                        break;
                    default:
                        break;
                }
            } else if (resultCode == RESULT_CANCELED) {
                // User pressed the system's back button, treat this like backToSafety().
                response.backToSafety(false);
            } else {
                throw new IllegalStateException("PopupInterstitialActivity shouldn't return any "
                        + "nonstandard resultCodes");
            }
        }

    }
}
