// 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.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.URLUtil;
import android.widget.FrameLayout;

import org.chromium.base.Callback;
import org.chromium.base.ContentUriUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.task.AsyncTask;
import org.chromium.content_public.browser.InvalidateTypes;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.content_public.common.ResourceRequestBody;

/**
 * Adapts the AwWebContentsDelegate interface to the AwContentsClient interface.
 * This class also serves a secondary function of routing certain callbacks from the content layer
 * to specific listener interfaces.
 */
class AwWebContentsDelegateAdapter extends AwWebContentsDelegate {
    private static final String TAG = "AwWebContentsDelegateAdapter";

    private final AwContents mAwContents;
    private final AwContentsClient mContentsClient;
    private final AwSettings mAwSettings;
    private final Context mContext;
    private View mContainerView;
    private FrameLayout mCustomView;

    public AwWebContentsDelegateAdapter(AwContents awContents, AwContentsClient contentsClient,
            AwSettings settings, Context context, View containerView) {
        mAwContents = awContents;
        mContentsClient = contentsClient;
        mAwSettings = settings;
        mContext = context;
        setContainerView(containerView);
    }

    public void setContainerView(View containerView) {
        mContainerView = containerView;
        mContainerView.setClickable(true);
    }

    @Override
    public void onLoadProgressChanged(int progress) {
        mContentsClient.getCallbackHelper().postOnProgressChanged(progress);
    }

    @Override
    public void handleKeyboardEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            int direction;
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    direction = View.FOCUS_DOWN;
                    break;
                case KeyEvent.KEYCODE_DPAD_UP:
                    direction = View.FOCUS_UP;
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    direction = View.FOCUS_LEFT;
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    direction = View.FOCUS_RIGHT;
                    break;
                default:
                    direction = 0;
                    break;
            }
            if (direction != 0 && tryToMoveFocus(direction)) return;
        }
        handleMediaKey(event);
        mContentsClient.onUnhandledKeyEvent(event);
    }

    /**
     * Redispatches unhandled media keys. This allows bluetooth headphones with play/pause or
     * other buttons to function correctly.
     */
    private void handleMediaKey(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.KEYCODE_MUTE:
            case KeyEvent.KEYCODE_HEADSETHOOK:
            case KeyEvent.KEYCODE_MEDIA_PLAY:
            case KeyEvent.KEYCODE_MEDIA_PAUSE:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
            case KeyEvent.KEYCODE_MEDIA_STOP:
            case KeyEvent.KEYCODE_MEDIA_NEXT:
            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
            case KeyEvent.KEYCODE_MEDIA_REWIND:
            case KeyEvent.KEYCODE_MEDIA_RECORD:
            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
            case KeyEvent.KEYCODE_MEDIA_CLOSE:
            case KeyEvent.KEYCODE_MEDIA_EJECT:
            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
                AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
                am.dispatchMediaKeyEvent(e);
                break;
            default:
                break;
        }
    }

    @Override
    public boolean takeFocus(boolean reverse) {
        int direction =
                (reverse == (mContainerView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL))
                ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
        if (tryToMoveFocus(direction)) return true;
        direction = reverse ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
        return tryToMoveFocus(direction);
    }

    private boolean tryToMoveFocus(int direction) {
        View focus = mContainerView.focusSearch(direction);
        return focus != null && focus != mContainerView && focus.requestFocus();
    }

    @Override
    public boolean addMessageToConsole(int level, String message, int lineNumber,
            String sourceId) {
        @AwConsoleMessage.MessageLevel
        int messageLevel = AwConsoleMessage.MESSAGE_LEVEL_DEBUG;
        switch(level) {
            case LOG_LEVEL_TIP:
                messageLevel = AwConsoleMessage.MESSAGE_LEVEL_TIP;
                break;
            case LOG_LEVEL_LOG:
                messageLevel = AwConsoleMessage.MESSAGE_LEVEL_LOG;
                break;
            case LOG_LEVEL_WARNING:
                messageLevel = AwConsoleMessage.MESSAGE_LEVEL_WARNING;
                break;
            case LOG_LEVEL_ERROR:
                messageLevel = AwConsoleMessage.MESSAGE_LEVEL_ERROR;
                break;
            default:
                Log.w(TAG, "Unknown message level, defaulting to DEBUG");
                break;
        }

        boolean result = mContentsClient.onConsoleMessage(
                new AwConsoleMessage(message, sourceId, lineNumber, messageLevel));
        if (result && message != null && message.startsWith("[blocked]")) {
            Log.e(TAG, "Blocked URL: " + message);
        }
        return result;
    }

    @Override
    public void onUpdateUrl(String url) {
        // TODO: implement
    }

    @Override
    public void openNewTab(String url, String extraHeaders, ResourceRequestBody postData,
            int disposition, boolean isRendererInitiated) {
        // This is only called in chrome layers.
        assert false;
    }

    @Override
    public void closeContents() {
        mContentsClient.onCloseWindow();
    }

    @Override
    public void showRepostFormWarningDialog() {
        // TODO(mkosiba) We should be using something akin to the JsResultReceiver as the
        // callback parameter (instead of WebContents) and implement a way of converting
        // that to a pair of messages.
        final int msgContinuePendingReload = 1;
        final int msgCancelPendingReload = 2;

        // TODO(sgurun) Remember the URL to cancel the reload behavior
        // if it is different than the most recent NavigationController entry.
        final Handler handler = new Handler(ThreadUtils.getUiThreadLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (mAwContents.getNavigationController() == null) return;

                switch(msg.what) {
                    case msgContinuePendingReload: {
                        mAwContents.getNavigationController().continuePendingReload();
                        break;
                    }
                    case msgCancelPendingReload: {
                        mAwContents.getNavigationController().cancelPendingReload();
                        break;
                    }
                    default:
                        throw new IllegalStateException(
                                "WebContentsDelegateAdapter: unhandled message " + msg.what);
                }
            }
        };

        Message resend = handler.obtainMessage(msgContinuePendingReload);
        Message dontResend = handler.obtainMessage(msgCancelPendingReload);
        mContentsClient.getCallbackHelper().postOnFormResubmission(dontResend, resend);
    }

    @Override
    public void runFileChooser(final int processId, final int renderId, final int modeFlags,
            String acceptTypes, String title, String defaultFilename, boolean capture) {
        AwContentsClient.FileChooserParamsImpl params = new AwContentsClient.FileChooserParamsImpl(
                modeFlags, acceptTypes, title, defaultFilename, capture);

        mContentsClient.showFileChooser(new Callback<String[]>() {
            boolean mCompleted;
            @Override
            public void onResult(String[] results) {
                if (mCompleted) {
                    throw new IllegalStateException("Duplicate showFileChooser result");
                }
                mCompleted = true;
                if (results == null) {
                    nativeFilesSelectedInChooser(
                            processId, renderId, modeFlags, null, null);
                    return;
                }
                GetDisplayNameTask task =
                        new GetDisplayNameTask(mContext, processId, renderId, modeFlags, results);
                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
        }, params);
    }

    @Override
    public boolean addNewContents(boolean isDialog, boolean isUserGesture) {
        return mContentsClient.onCreateWindow(isDialog, isUserGesture);
    }

    @Override
    public void activateContents() {
        mContentsClient.onRequestFocus();
    }

    @Override
    public void navigationStateChanged(int flags) {
        if ((flags & InvalidateTypes.URL) != 0
                && mAwContents.isPopupWindow()
                && mAwContents.hasAccessedInitialDocument()) {
            // Hint the client to show the last committed url, as it may be unsafe to show
            // the pending entry.
            String url = mAwContents.getLastCommittedUrl();
            url = TextUtils.isEmpty(url) ? ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL : url;
            mContentsClient.getCallbackHelper().postSynthesizedPageLoadingForUrlBarUpdate(url);
        }
    }

    @Override
    public void enterFullscreenModeForTab(boolean prefersNavigationBar) {
        enterFullscreen();
    }

    @Override
    public void exitFullscreenModeForTab() {
        exitFullscreen();
    }

    @Override
    public void loadingStateChanged() {
        mContentsClient.updateTitle(mAwContents.getTitle(), false);
    }

    /**
     * Called to show the web contents in fullscreen mode.
     *
     * <p>If entering fullscreen on a video element the web contents will contain just
     * the html5 video controls. {@link #enterFullscreenVideo(View)} will be called later
     * once the ContentVideoView, which contains the hardware accelerated fullscreen video,
     * is ready to be shown.
     */
    private void enterFullscreen() {
        if (mAwContents.isFullScreen()) {
            return;
        }
        View fullscreenView = mAwContents.enterFullScreen();
        if (fullscreenView == null) {
            return;
        }
        AwContentsClient.CustomViewCallback cb = () -> {
            if (mCustomView != null) {
                mAwContents.requestExitFullscreen();
            }
        };
        mCustomView = new FrameLayout(mContext);
        mCustomView.addView(fullscreenView);
        mContentsClient.onShowCustomView(mCustomView, cb);
    }

    /**
     * Called to show the web contents in embedded mode.
     */
    private void exitFullscreen() {
        if (mCustomView != null) {
            mCustomView = null;
            mAwContents.exitFullScreen();
            mContentsClient.onHideCustomView();
        }
    }

    @Override
    public boolean shouldBlockMediaRequest(String url) {
        return mAwSettings != null
                ? mAwSettings.getBlockNetworkLoads() && URLUtil.isNetworkUrl(url) : true;
    }

    private static class GetDisplayNameTask extends AsyncTask<String[]> {
        final int mProcessId;
        final int mRenderId;
        final int mModeFlags;
        final String[] mFilePaths;

        // The task doesn't run long, so we don't gain anything from a weak ref.
        @SuppressLint("StaticFieldLeak")
        final Context mContext;

        public GetDisplayNameTask(
                Context context, int processId, int renderId, int modeFlags, String[] filePaths) {
            mProcessId = processId;
            mRenderId = renderId;
            mModeFlags = modeFlags;
            mFilePaths = filePaths;
            mContext = context;
        }

        @Override
        protected String[] doInBackground() {
            String[] displayNames = new String[mFilePaths.length];
            for (int i = 0; i < mFilePaths.length; i++) {
                displayNames[i] = resolveFileName(mFilePaths[i]);
            }
            return displayNames;
        }

        @Override
        protected void onPostExecute(String[] result) {
            nativeFilesSelectedInChooser(mProcessId, mRenderId, mModeFlags, mFilePaths, result);
        }

        /**
         * @return the display name of a path if it is a content URI and is present in the database
         * or an empty string otherwise.
         */
        private String resolveFileName(String filePath) {
            if (filePath == null) return "";
            Uri uri = Uri.parse(filePath);
            return ContentUriUtils.getDisplayName(
                    uri, mContext, MediaStore.MediaColumns.DISPLAY_NAME);
        }
    }
}
