// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.android_webview;

import android.graphics.Picture;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;

import org.chromium.base.Callback;
import org.chromium.base.VisibleForTesting;

import java.util.concurrent.Callable;

/**
 * This class is responsible for calling certain client callbacks on the UI thread.
 *
 * Most callbacks do no go through here, but get forwarded to AwContentsClient directly. The
 * messages processed here may originate from the IO or UI thread.
 */
@VisibleForTesting
public class AwContentsClientCallbackHelper {
    /**
     * Interface to tell CallbackHelper to cancel posted callbacks.
     */
    public static interface CancelCallbackPoller { boolean shouldCancelAllCallbacks(); }

    // TODO(boliu): Consider removing DownloadInfo and LoginRequestInfo by using native
    // MessageLoop to post directly to AwContents.

    private static class DownloadInfo {
        final String mUrl;
        final String mUserAgent;
        final String mContentDisposition;
        final String mMimeType;
        final long mContentLength;

        DownloadInfo(String url,
                     String userAgent,
                     String contentDisposition,
                     String mimeType,
                     long contentLength) {
            mUrl = url;
            mUserAgent = userAgent;
            mContentDisposition = contentDisposition;
            mMimeType = mimeType;
            mContentLength = contentLength;
        }
    }

    private static class LoginRequestInfo {
        final String mRealm;
        final String mAccount;
        final String mArgs;

        LoginRequestInfo(String realm, String account, String args) {
            mRealm = realm;
            mAccount = account;
            mArgs = args;
        }
    }

    private static class OnReceivedErrorInfo {
        final AwContentsClient.AwWebResourceRequest mRequest;
        final AwContentsClient.AwWebResourceError mError;

        OnReceivedErrorInfo(AwContentsClient.AwWebResourceRequest request,
                AwContentsClient.AwWebResourceError error) {
            mRequest = request;
            mError = error;
        }
    }

    private static class OnSafeBrowsingHitInfo {
        final AwContentsClient.AwWebResourceRequest mRequest;
        final int mThreatType;
        final Callback<AwSafeBrowsingResponse> mCallback;

        OnSafeBrowsingHitInfo(AwContentsClient.AwWebResourceRequest request, int threatType,
                Callback<AwSafeBrowsingResponse> callback) {
            mRequest = request;
            mThreatType = threatType;
            mCallback = callback;
        }
    }

    private static class OnReceivedHttpErrorInfo {
        final AwContentsClient.AwWebResourceRequest mRequest;
        final AwWebResourceResponse mResponse;

        OnReceivedHttpErrorInfo(
                AwContentsClient.AwWebResourceRequest request, AwWebResourceResponse response) {
            mRequest = request;
            mResponse = response;
        }
    }

    private static class DoUpdateVisitedHistoryInfo {
        final String mUrl;
        final boolean mIsReload;

        DoUpdateVisitedHistoryInfo(String url, boolean isReload) {
            mUrl = url;
            mIsReload = isReload;
        }
    }

    private static class OnFormResubmissionInfo {
        final Message mDontResend;
        final Message mResend;

        OnFormResubmissionInfo(Message dontResend, Message resend) {
            mDontResend = dontResend;
            mResend = resend;
        }
    }

    private static final int MSG_ON_LOAD_RESOURCE = 1;
    private static final int MSG_ON_PAGE_STARTED = 2;
    private static final int MSG_ON_DOWNLOAD_START = 3;
    private static final int MSG_ON_RECEIVED_LOGIN_REQUEST = 4;
    private static final int MSG_ON_RECEIVED_ERROR = 5;
    private static final int MSG_ON_NEW_PICTURE = 6;
    private static final int MSG_ON_SCALE_CHANGED_SCALED = 7;
    private static final int MSG_ON_RECEIVED_HTTP_ERROR = 8;
    private static final int MSG_ON_PAGE_FINISHED = 9;
    private static final int MSG_ON_RECEIVED_TITLE = 10;
    private static final int MSG_ON_PROGRESS_CHANGED = 11;
    private static final int MSG_SYNTHESIZE_PAGE_LOADING = 12;
    private static final int MSG_DO_UPDATE_VISITED_HISTORY = 13;
    private static final int MSG_ON_FORM_RESUBMISSION = 14;
    private static final int MSG_ON_SAFE_BROWSING_HIT = 15;

    // Minimum period allowed between consecutive onNewPicture calls, to rate-limit the callbacks.
    private static final long ON_NEW_PICTURE_MIN_PERIOD_MILLIS = 500;
    // Timestamp of the most recent onNewPicture callback.
    private long mLastPictureTime;
    // True when a onNewPicture callback is currenly in flight.
    private boolean mHasPendingOnNewPicture;

    private final AwContentsClient mContentsClient;

    private final Handler mHandler;

    private CancelCallbackPoller mCancelCallbackPoller;

    private class MyHandler extends Handler {
        private MyHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            if (mCancelCallbackPoller != null && mCancelCallbackPoller.shouldCancelAllCallbacks()) {
                removeCallbacksAndMessages(null);
                return;
            }

            switch(msg.what) {
                case MSG_ON_LOAD_RESOURCE: {
                    final String url = (String) msg.obj;
                    mContentsClient.onLoadResource(url);
                    break;
                }
                case MSG_ON_PAGE_STARTED: {
                    final String url = (String) msg.obj;
                    mContentsClient.onPageStarted(url);
                    break;
                }
                case MSG_ON_DOWNLOAD_START: {
                    DownloadInfo info = (DownloadInfo) msg.obj;
                    mContentsClient.onDownloadStart(info.mUrl, info.mUserAgent,
                            info.mContentDisposition, info.mMimeType, info.mContentLength);
                    break;
                }
                case MSG_ON_RECEIVED_LOGIN_REQUEST: {
                    LoginRequestInfo info = (LoginRequestInfo) msg.obj;
                    mContentsClient.onReceivedLoginRequest(info.mRealm, info.mAccount, info.mArgs);
                    break;
                }
                case MSG_ON_RECEIVED_ERROR: {
                    OnReceivedErrorInfo info = (OnReceivedErrorInfo) msg.obj;
                    mContentsClient.onReceivedError(info.mRequest, info.mError);
                    break;
                }
                case MSG_ON_SAFE_BROWSING_HIT: {
                    OnSafeBrowsingHitInfo info = (OnSafeBrowsingHitInfo) msg.obj;
                    mContentsClient.onSafeBrowsingHit(
                            info.mRequest, info.mThreatType, info.mCallback);
                    break;
                }
                case MSG_ON_NEW_PICTURE: {
                    Picture picture = null;
                    try {
                        if (msg.obj != null) picture = (Picture) ((Callable<?>) msg.obj).call();
                    } catch (Exception e) {
                        throw new RuntimeException("Error getting picture", e);
                    }
                    mContentsClient.onNewPicture(picture);
                    mLastPictureTime = SystemClock.uptimeMillis();
                    mHasPendingOnNewPicture = false;
                    break;
                }
                case MSG_ON_SCALE_CHANGED_SCALED: {
                    float oldScale = Float.intBitsToFloat(msg.arg1);
                    float newScale = Float.intBitsToFloat(msg.arg2);
                    mContentsClient.onScaleChangedScaled(oldScale, newScale);
                    break;
                }
                case MSG_ON_RECEIVED_HTTP_ERROR: {
                    OnReceivedHttpErrorInfo info = (OnReceivedHttpErrorInfo) msg.obj;
                    mContentsClient.onReceivedHttpError(info.mRequest, info.mResponse);
                    break;
                }
                case MSG_ON_PAGE_FINISHED: {
                    final String url = (String) msg.obj;
                    mContentsClient.onPageFinished(url);
                    break;
                }
                case MSG_ON_RECEIVED_TITLE: {
                    final String title = (String) msg.obj;
                    mContentsClient.onReceivedTitle(title);
                    break;
                }
                case MSG_ON_PROGRESS_CHANGED: {
                    mContentsClient.onProgressChanged(msg.arg1);
                    break;
                }
                case MSG_SYNTHESIZE_PAGE_LOADING: {
                    final String url = (String) msg.obj;
                    mContentsClient.onPageStarted(url);
                    mContentsClient.onLoadResource(url);
                    mContentsClient.onProgressChanged(100);
                    mContentsClient.onPageFinished(url);
                    break;
                }
                case MSG_DO_UPDATE_VISITED_HISTORY: {
                    final DoUpdateVisitedHistoryInfo info = (DoUpdateVisitedHistoryInfo) msg.obj;
                    mContentsClient.doUpdateVisitedHistory(info.mUrl, info.mIsReload);
                    break;
                }
                case MSG_ON_FORM_RESUBMISSION: {
                    final OnFormResubmissionInfo info = (OnFormResubmissionInfo) msg.obj;
                    mContentsClient.onFormResubmission(info.mDontResend, info.mResend);
                    break;
                }
                default:
                    throw new IllegalStateException(
                            "AwContentsClientCallbackHelper: unhandled message " + msg.what);
            }
        }
    }

    public AwContentsClientCallbackHelper(Looper looper, AwContentsClient contentsClient) {
        mHandler = new MyHandler(looper);
        mContentsClient = contentsClient;
    }

    // Public for tests.
    public void setCancelCallbackPoller(CancelCallbackPoller poller) {
        mCancelCallbackPoller = poller;
    }

    CancelCallbackPoller getCancelCallbackPoller() {
        return mCancelCallbackPoller;
    }

    public void postOnLoadResource(String url) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_LOAD_RESOURCE, url));
    }

    public void postOnPageStarted(String url) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_PAGE_STARTED, url));
    }

    public void postOnDownloadStart(String url, String userAgent, String contentDisposition,
            String mimeType, long contentLength) {
        DownloadInfo info = new DownloadInfo(url, userAgent, contentDisposition, mimeType,
                contentLength);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_DOWNLOAD_START, info));
    }

    public void postOnReceivedLoginRequest(String realm, String account, String args) {
        LoginRequestInfo info = new LoginRequestInfo(realm, account, args);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_LOGIN_REQUEST, info));
    }

    public void postOnReceivedError(AwContentsClient.AwWebResourceRequest request,
            AwContentsClient.AwWebResourceError error) {
        OnReceivedErrorInfo info = new OnReceivedErrorInfo(request, error);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_ERROR, info));
    }

    public void postOnSafeBrowsingHit(AwContentsClient.AwWebResourceRequest request, int threatType,
            Callback<AwSafeBrowsingResponse> callback) {
        OnSafeBrowsingHitInfo info = new OnSafeBrowsingHitInfo(request, threatType, callback);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_SAFE_BROWSING_HIT, info));
    }

    public void postOnNewPicture(Callable<Picture> pictureProvider) {
        if (mHasPendingOnNewPicture) return;
        mHasPendingOnNewPicture = true;
        long pictureTime = java.lang.Math.max(mLastPictureTime + ON_NEW_PICTURE_MIN_PERIOD_MILLIS,
                SystemClock.uptimeMillis());
        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ON_NEW_PICTURE, pictureProvider),
                pictureTime);
    }

    public void postOnScaleChangedScaled(float oldScale, float newScale) {
        // The float->int->float conversion here is to avoid unnecessary allocations. The
        // documentation states that intBitsToFloat(floatToIntBits(a)) == a for all values of a
        // (except for NaNs which are collapsed to a single canonical NaN, but we don't care for
        // that case).
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_SCALE_CHANGED_SCALED,
                    Float.floatToIntBits(oldScale), Float.floatToIntBits(newScale)));
    }

    public void postOnReceivedHttpError(AwContentsClient.AwWebResourceRequest request,
            AwWebResourceResponse response) {
        OnReceivedHttpErrorInfo info =
                new OnReceivedHttpErrorInfo(request, response);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_HTTP_ERROR, info));
    }

    public void postOnPageFinished(String url) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_PAGE_FINISHED, url));
    }

    public void postOnReceivedTitle(String title) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_TITLE, title));
    }

    public void postOnProgressChanged(int progress) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_PROGRESS_CHANGED, progress, 0));
    }

    public void postSynthesizedPageLoadingForUrlBarUpdate(String url) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_SYNTHESIZE_PAGE_LOADING, url));
    }

    public void postDoUpdateVisitedHistory(String url, boolean isReload) {
        DoUpdateVisitedHistoryInfo info = new DoUpdateVisitedHistoryInfo(url, isReload);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_DO_UPDATE_VISITED_HISTORY, info));
    }

    public void postOnFormResubmission(Message dontResend, Message resend) {
        OnFormResubmissionInfo info = new OnFormResubmissionInfo(dontResend, resend);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_FORM_RESUBMISSION, info));
    }

    void removeCallbacksAndMessages() {
        mHandler.removeCallbacksAndMessages(null);
    }
}
